Static Value-Flow Analysis
Classes | Macros | Typedefs | Functions | Variables
cuddInt.c File Reference
#include "CUDD/util.h"
#include "CUDD/cuddInt.h"

Go to the source code of this file.

Classes

struct  cuddPathPair
 
union  hack
 

Macros

#define BETA   0.6
 
#define ALPHA   0.90
 
#define EXC_PROB   0.4
 
#define JUMP_UP_PROB   0.36
 
#define MAXGEN_RATIO   15.0
 
#define STOP_TEMP   1.0
 
#define STOREDD(i, j)   storedd[(i)*(numvars+1)+(j)]
 
#define DD_NORMAL_SIFT   0
 
#define DD_LAZY_SIFT   1
 
#define DD_SIFT_DOWN   0
 
#define DD_SIFT_UP   1
 
#define BPL   32
 
#define LOGBPL   5
 
#define DD_MAX_HASHTABLE_DENSITY   2 /* tells when to resize a table */
 
#define ddLCHash1(f, shift)   (((unsigned)(f) * DD_P1) >> (shift))
 
#define ddLCHash2(f, g, shift)   ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift))
 
#define ddLCHash3(f, g, h, shift)   ddCHash2(f,g,h,shift)
 
#define CUDD_SWAP_MOVE   0
 
#define CUDD_LINEAR_TRANSFORM_MOVE   1
 
#define CUDD_INVERSE_TRANSFORM_MOVE   2
 
#define BPL   32
 
#define LOGBPL   5
 
#define DD_MAX_SUBTABLE_SPARSITY   8
 
#define DD_BIGGY   100000000
 
#define WEIGHT(weight, col)   ((weight) == NULL ? 1 : weight[col])
 
#define MV_OOM   (Move *)1
 
#define MODULUS1   2147483563
 
#define LEQA1   40014
 
#define LEQQ1   53668
 
#define LEQR1   12211
 
#define MODULUS2   2147483399
 
#define LEQA2   40692
 
#define LEQQ2   52774
 
#define LEQR2   3791
 
#define STAB_SIZE   64
 
#define STAB_DIV   (1 + (MODULUS1 - 1) / STAB_SIZE)
 
#define bang(f)   ((Cudd_IsComplement(f)) ? '!' : ' ')
 
#define ABC   1
 
#define BAC   2
 
#define BCA   3
 
#define CBA   4
 
#define CAB   5
 
#define ACB   6
 
#define ABCD   1
 
#define BACD   7
 
#define BADC   13
 
#define ABDC   8
 
#define ADBC   14
 
#define ADCB   9
 
#define DACB   15
 
#define DABC   20
 
#define DBAC   23
 
#define BDAC   19
 
#define BDCA   21
 
#define DBCA   24
 
#define DCBA   22
 
#define DCAB   18
 
#define CDAB   12
 
#define CDBA   17
 
#define CBDA   11
 
#define BCDA   16
 
#define BCAD   10
 
#define CBAD   5
 
#define CABD   3
 
#define CADB   6
 
#define ACDB   4
 
#define ACBD   2
 
#define CUDD_SWAP_MOVE   0
 
#define CUDD_LINEAR_TRANSFORM_MOVE   1
 
#define CUDD_INVERSE_TRANSFORM_MOVE   2
 
#define DD_MAX_SUBTABLE_SPARSITY   8
 
#define ZDD_MV_OOM   (Move *)1
 

Typedefs

typedef int(* DD_CHKFP) (DdManager *, int, int)
 
typedef struct cuddPathPair cuddPathPair
 
typedef union hack hack
 

Functions

static void addVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero)
 
DdNodeCudd_addIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
 
DdNodeCudd_addEvalConst (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodeCudd_addCmpl (DdManager *dd, DdNode *f)
 
int Cudd_addLeq (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddAddIteRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
 
DdNodecuddAddCmplRecur (DdManager *dd, DdNode *f)
 
static int stopping_criterion (int c1, int c2, int c3, int c4, double temp)
 
static double random_generator (void)
 
static int ddExchange (DdManager *table, int x, int y, double temp)
 
static int ddJumpingAux (DdManager *table, int x, int x_low, int x_high, double temp)
 
static MoveddJumpingUp (DdManager *table, int x, int x_low, int initial_size)
 
static MoveddJumpingDown (DdManager *table, int x, int x_high, int initial_size)
 
static int siftBackwardProb (DdManager *table, Move *moves, int size, double temp)
 
static void copyOrder (DdManager *table, int *array, int lower, int upper)
 
static int restoreOrder (DdManager *table, int *array, int lower, int upper)
 
int cuddAnnealing (DdManager *table, int lower, int upper)
 
static void fixVarTree (MtrNode *treenode, int *perm, int size)
 
static int addMultiplicityGroups (DdManager *dd, MtrNode *treenode, int multiplicity, char *vmask, char *lmask)
 
DdNodeCudd_bddIthVar (DdManager *dd, int i)
 
DdNodeCudd_ReadOne (DdManager *dd)
 
DdNodeCudd_ReadLogicZero (DdManager *dd)
 
void Cudd_SetMinHit (DdManager *dd, unsigned int hr)
 
int Cudd_ReadSize (DdManager *dd)
 
void Cudd_FreeTree (DdManager *dd)
 
void Cudd_FreeZddTree (DdManager *dd)
 
int Cudd_ReadPerm (DdManager *dd, int i)
 
CUDD_VALUE_TYPE Cudd_ReadEpsilon (DdManager *dd)
 
void Cudd_SetEpsilon (DdManager *dd, CUDD_VALUE_TYPE ep)
 
unsigned long Cudd_ReadMemoryInUse (DdManager *dd)
 
long Cudd_ReadNodeCount (DdManager *dd)
 
int Cudd_RemoveHook (DdManager *dd, DD_HFP f, Cudd_HookType where)
 
int Cudd_bddReadPairIndex (DdManager *dd, int index)
 
int Cudd_bddIsVarToBeGrouped (DdManager *dd, int index)
 
int Cudd_bddIsVarToBeUngrouped (DdManager *dd, int index)
 
static int bddCheckPositiveCube (DdManager *manager, DdNode *cube)
 
DdNodeCudd_bddExistAbstract (DdManager *manager, DdNode *f, DdNode *cube)
 
int Cudd_bddVarIsDependent (DdManager *dd, DdNode *f, DdNode *var)
 
DdNodecuddBddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube)
 
DdNodecuddBddXorExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
 
DdNodecuddBddBooleanDiffRecur (DdManager *manager, DdNode *f, DdNode *var)
 
static void bddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *one)
 
static int bddVarToCanonical (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
 
static int bddVarToCanonicalSimple (DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
 
DdNodeCudd_bddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
 
DdNodeCudd_bddIteConstant (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
 
DdNodeCudd_bddIntersect (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodeCudd_bddAnd (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodeCudd_bddAndLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit)
 
DdNodeCudd_bddOr (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodeCudd_bddOrLimit (DdManager *dd, DdNode *f, DdNode *g, unsigned int limit)
 
DdNodeCudd_bddXor (DdManager *dd, DdNode *f, DdNode *g)
 
int Cudd_bddLeq (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddBddIteRecur (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
 
DdNodecuddBddIntersectRecur (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddBddAndRecur (DdManager *manager, DdNode *f, DdNode *g)
 
DdNodecuddBddXorRecur (DdManager *manager, DdNode *f, DdNode *g)
 
int cuddInitCache (DdManager *unique, unsigned int cacheSize, unsigned int maxCacheSize)
 
void cuddCacheInsert (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
 
void cuddCacheInsert2 (DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
 
void cuddCacheInsert1 (DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
 
DdNodecuddCacheLookup (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
 
DdNodecuddCacheLookupZdd (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
 
DdNodecuddCacheLookup2 (DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
 
DdNodecuddCacheLookup1 (DdManager *table, DD_CTFP1 op, DdNode *f)
 
DdNodecuddCacheLookup2Zdd (DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
 
DdNodecuddCacheLookup1Zdd (DdManager *table, DD_CTFP1 op, DdNode *f)
 
DdNodecuddConstantLookup (DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
 
int cuddCacheProfile (DdManager *table, FILE *fp)
 
void cuddCacheResize (DdManager *table)
 
void cuddCacheFlush (DdManager *table)
 
int cuddComputeFloorLog2 (unsigned int value)
 
static void debugFindParent (DdManager *table, DdNode *node)
 
int Cudd_DebugCheck (DdManager *table)
 
int Cudd_CheckKeys (DdManager *table)
 
int cuddHeapProfile (DdManager *dd)
 
void cuddPrintNode (DdNode *f, FILE *fp)
 
void cuddPrintVarGroups (DdManager *dd, MtrNode *root, int zdd, int silent)
 
DdNodeCudd_Cofactor (DdManager *dd, DdNode *f, DdNode *g)
 
int Cudd_CheckCube (DdManager *dd, DdNode *g)
 
void cuddGetBranches (DdNode *g, DdNode **g1, DdNode **g0)
 
DdNodecuddCofactorRecur (DdManager *dd, DdNode *f, DdNode *g)
 
static int getMaxBinomial (int n)
 
static DdHalfWord ** getMatrix (int rows, int cols)
 
static void freeMatrix (DdHalfWord **matrix)
 
static int getLevelKeys (DdManager *table, int l)
 
static int ddShuffle (DdManager *table, DdHalfWord *permutation, int lower, int upper)
 
static int ddSiftUp (DdManager *table, int x, int xLow)
 
static int updateUB (DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper)
 
static int ddCountRoots (DdManager *table, int lower, int upper)
 
static void ddClearGlobal (DdManager *table, int lower, int maxlevel)
 
static int computeLB (DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level)
 
static int updateEntry (DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper)
 
static void pushDown (DdHalfWord *order, int j, int level)
 
static DdHalfWordinitSymmInfo (DdManager *table, int lower, int upper)
 
static int checkSymmInfo (DdManager *table, DdHalfWord *symmInfo, int index, int level)
 
int cuddExact (DdManager *table, int lower, int upper)
 
static int make_random (DdManager *table, int lower)
 
static int sift_up (DdManager *table, int x, int x_low)
 
static int build_dd (DdManager *table, int num, int lower, int upper)
 
static int largest (void)
 
static int rand_int (int a)
 
static int array_hash (char *array, int modulus)
 
static int array_compare (const char *array1, const char *array2)
 
static int find_best (void)
 
static int PMX (int maxvar)
 
static int roulette (int *p1, int *p2)
 
int cuddGa (DdManager *table, int lower, int upper)
 
static int ddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
 
static int ddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
 
static void ddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper)
 
static int ddUniqueCompareGroup (int *ptrX, int *ptrY)
 
static int ddGroupSifting (DdManager *table, int lower, int upper, DD_CHKFP checkFunction, int lazyFlag)
 
static void ddCreateGroup (DdManager *table, int x, int y)
 
static int ddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh, DD_CHKFP checkFunction, int lazyFlag)
 
static int ddGroupSiftingUp (DdManager *table, int y, int xLow, DD_CHKFP checkFunction, Move **moves)
 
static int ddGroupSiftingDown (DdManager *table, int x, int xHigh, DD_CHKFP checkFunction, Move **moves)
 
static int ddGroupMove (DdManager *table, int x, int y, Move **moves)
 
static int ddGroupMoveBackward (DdManager *table, int x, int y)
 
static int ddGroupSiftingBackward (DdManager *table, Move *moves, int size, int upFlag, int lazyFlag)
 
static void ddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high)
 
static void ddDissolveGroup (DdManager *table, int x, int y)
 
static int ddNoCheck (DdManager *table, int x, int y)
 
static int ddSecDiffCheck (DdManager *table, int x, int y)
 
static int ddExtSymmCheck (DdManager *table, int x, int y)
 
static int ddVarGroupCheck (DdManager *table, int x, int y)
 
static int ddSetVarHandled (DdManager *dd, int index)
 
static int ddResetVarHandled (DdManager *dd, int index)
 
static int ddIsVarHandled (DdManager *dd, int index)
 
int cuddTreeSifting (DdManager *table, Cudd_ReorderingType method)
 
DdManagerCudd_Init (unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int cacheSize, unsigned long maxMemory)
 
void Cudd_Quit (DdManager *unique)
 
int cuddZddInitUniv (DdManager *zdd)
 
void cuddZddFreeUniv (DdManager *zdd)
 
static void ddSuppInteract (DdNode *f, char *support)
 
static void ddClearLocal (DdNode *f)
 
static void ddUpdateInteract (DdManager *table, char *support)
 
static void ddClearGlobal2 (DdManager *table)
 
void cuddSetInteract (DdManager *table, int x, int y)
 
int cuddTestInteract (DdManager *table, int x, int y)
 
int cuddInitInteract (DdManager *table)
 
static void cuddLocalCacheResize (DdLocalCache *cache)
 
static DD_INLINE unsigned int ddLCHash (DdNodePtr *key, unsigned int keysize, int shift)
 
static void cuddLocalCacheAddToList (DdLocalCache *cache)
 
static void cuddLocalCacheRemoveFromList (DdLocalCache *cache)
 
static int cuddHashTableResize (DdHashTable *hash)
 
static DD_INLINE DdHashItemcuddHashTableAlloc (DdHashTable *hash)
 
void cuddLocalCacheClearDead (DdManager *manager)
 
void cuddLocalCacheClearAll (DdManager *manager)
 
DdHashTablecuddHashTableInit (DdManager *manager, unsigned int keySize, unsigned int initSize)
 
void cuddHashTableQuit (DdHashTable *hash)
 
void cuddHashTableGenericQuit (DdHashTable *hash)
 
int cuddHashTableInsert (DdHashTable *hash, DdNodePtr *key, DdNode *value, ptrint count)
 
DdNodecuddHashTableLookup (DdHashTable *hash, DdNodePtr *key)
 
int cuddHashTableInsert1 (DdHashTable *hash, DdNode *f, DdNode *value, ptrint count)
 
DdNodecuddHashTableLookup1 (DdHashTable *hash, DdNode *f)
 
int cuddHashTableGenericInsert (DdHashTable *hash, DdNode *f, void *value)
 
void * cuddHashTableGenericLookup (DdHashTable *hash, DdNode *f)
 
int cuddHashTableInsert2 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *value, ptrint count)
 
DdNodecuddHashTableLookup2 (DdHashTable *hash, DdNode *f, DdNode *g)
 
int cuddHashTableInsert3 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h, DdNode *value, ptrint count)
 
DdNodecuddHashTableLookup3 (DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h)
 
static int ddLinearUniqueCompare (int *ptrX, int *ptrY)
 
static int ddLinearAndSiftingAux (DdManager *table, int x, int xLow, int xHigh)
 
static MoveddLinearAndSiftingUp (DdManager *table, int y, int xLow, Move *prevMoves)
 
static MoveddLinearAndSiftingDown (DdManager *table, int x, int xHigh, Move *prevMoves)
 
static int ddLinearAndSiftingBackward (DdManager *table, int size, Move *moves)
 
static MoveddUndoMoves (DdManager *table, Move *moves)
 
static void cuddXorLinear (DdManager *table, int x, int y)
 
int Cudd_PrintLinear (DdManager *table)
 
int cuddLinearAndSifting (DdManager *table, int lower, int upper)
 
int cuddLinearInPlace (DdManager *table, int x, int y)
 
void cuddUpdateInteractionMatrix (DdManager *table, int xindex, int yindex)
 
int cuddInitLinear (DdManager *table)
 
int cuddResizeLinear (DdManager *table)
 
void Cudd_Ref (DdNode *n)
 
void Cudd_RecursiveDeref (DdManager *table, DdNode *n)
 
void Cudd_IterDerefBdd (DdManager *table, DdNode *n)
 
void Cudd_RecursiveDerefZdd (DdManager *table, DdNode *n)
 
void Cudd_Deref (DdNode *node)
 
void cuddReclaim (DdManager *table, DdNode *n)
 
void cuddReclaimZdd (DdManager *table, DdNode *n)
 
void cuddShrinkDeathRow (DdManager *table)
 
void cuddClearDeathRow (DdManager *table)
 
static int ddUniqueCompare (int *ptrX, int *ptrY)
 
static MoveddSwapAny (DdManager *table, int x, int y)
 
static int ddSiftingAux (DdManager *table, int x, int xLow, int xHigh)
 
static MoveddSiftingUp (DdManager *table, int y, int xLow)
 
static MoveddSiftingDown (DdManager *table, int x, int xHigh)
 
static int ddSiftingBackward (DdManager *table, int size, Move *moves)
 
static int ddReorderPreprocess (DdManager *table)
 
static int ddReorderPostprocess (DdManager *table)
 
static int ddShuffle2 (DdManager *table, int *permutation)
 
static int ddSiftUp2 (DdManager *table, int x, int xLow)
 
static void bddFixTree (DdManager *table, MtrNode *treenode)
 
static int ddUpdateMtrTree (DdManager *table, MtrNode *treenode, int *perm, int *invperm)
 
static int ddCheckPermuation (DdManager *table, MtrNode *treenode, int *perm, int *invperm)
 
int Cudd_ReduceHeap (DdManager *table, Cudd_ReorderingType heuristic, int minsize)
 
DdNodecuddDynamicAllocNode (DdManager *table)
 
int cuddSifting (DdManager *table, int lower, int upper)
 
int cuddSwapping (DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)
 
int cuddNextHigh (DdManager *table, int x)
 
int cuddNextLow (DdManager *table, int x)
 
int cuddSwapInPlace (DdManager *table, int x, int y)
 
int cuddBddAlignToZdd (DdManager *table)
 
static enum st_retval freePathPair (char *key, char *value, char *arg)
 
static cuddPathPair getShortest (DdNode *root, int *cost, int *support, st_table *visited)
 
static cuddPathPair getLargest (DdNode *root, st_table *visited)
 
static DdNodegetCube (DdManager *manager, st_table *visited, DdNode *f, int cost)
 
static DdNodeddBddMaximallyExpand (DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f)
 
static int ddBddShortestPathUnate (DdManager *dd, DdNode *f, int *phases, st_table *table)
 
DdNodeCudd_LargestCube (DdManager *manager, DdNode *f, int *length)
 
DdNodeCudd_Decreasing (DdManager *dd, DdNode *f, int i)
 
int Cudd_EquivDC (DdManager *dd, DdNode *F, DdNode *G, DdNode *D)
 
int Cudd_bddLeqUnless (DdManager *dd, DdNode *f, DdNode *g, DdNode *D)
 
int Cudd_EqualSupNorm (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr)
 
DdNodeCudd_bddMakePrime (DdManager *dd, DdNode *cube, DdNode *f)
 
DdNodecuddBddMakePrime (DdManager *dd, DdNode *cube, DdNode *f)
 
static int ddSymmUniqueCompare (int *ptrX, int *ptrY)
 
static int ddSymmSiftingAux (DdManager *table, int x, int xLow, int xHigh)
 
static int ddSymmSiftingConvAux (DdManager *table, int x, int xLow, int xHigh)
 
static MoveddSymmSiftingUp (DdManager *table, int y, int xLow)
 
static MoveddSymmSiftingDown (DdManager *table, int x, int xHigh)
 
static int ddSymmGroupMove (DdManager *table, int x, int y, Move **moves)
 
static int ddSymmGroupMoveBackward (DdManager *table, int x, int y)
 
static int ddSymmSiftingBackward (DdManager *table, Move *moves, int size)
 
static void ddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups)
 
int cuddSymmCheck (DdManager *table, int x, int y)
 
int cuddSymmSifting (DdManager *table, int lower, int upper)
 
int cuddSymmSiftingConv (DdManager *table, int lower, int upper)
 
static void ddRehashZdd (DdManager *unique, int i)
 
static int ddResizeTable (DdManager *unique, int index, int amount)
 
static DD_INLINE void ddFixLimits (DdManager *unique)
 
static void ddPatchTree (DdManager *dd, MtrNode *treenode)
 
static void ddReportRefMess (DdManager *unique, int i, const char *caller)
 
DdNodecuddAllocNode (DdManager *unique)
 
DdManagercuddInitTable (unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int looseUpTo)
 
void cuddFreeTable (DdManager *unique)
 
int cuddGarbageCollect (DdManager *unique, int clearCache)
 
DdNodecuddZddGetNode (DdManager *zdd, int id, DdNode *T, DdNode *E)
 
DdNodecuddZddGetNodeIVO (DdManager *dd, int index, DdNode *g, DdNode *h)
 
DdNodecuddUniqueInter (DdManager *unique, int index, DdNode *T, DdNode *E)
 
DdNodecuddUniqueInterIVO (DdManager *unique, int index, DdNode *T, DdNode *E)
 
DdNodecuddUniqueInterZdd (DdManager *unique, int index, DdNode *T, DdNode *E)
 
DdNodecuddUniqueConst (DdManager *unique, CUDD_VALUE_TYPE value)
 
void cuddRehash (DdManager *unique, int i)
 
int cuddResizeTableZdd (DdManager *unique, int index)
 
void cuddSlowTableGrowth (DdManager *unique)
 
static int dp2 (DdManager *dd, DdNode *f, st_table *t)
 
static void ddPrintMintermAux (DdManager *dd, DdNode *node, int *list)
 
static int ddDagInt (DdNode *n)
 
static int cuddNodeArrayRecur (DdNode *f, DdNodePtr *table, int index)
 
static int cuddEstimateCofactor (DdManager *dd, st_table *table, DdNode *node, int i, int phase, DdNode **ptr)
 
static DdNodecuddUniqueLookup (DdManager *unique, int index, DdNode *T, DdNode *E)
 
static int cuddEstimateCofactorSimple (DdNode *node, int i)
 
static double ddCountMintermAux (DdNode *node, double max, DdHashTable *table)
 
static int ddEpdCountMintermAux (DdNode *node, EpDouble *max, EpDouble *epd, st_table *table)
 
static double ddCountPathAux (DdNode *node, st_table *table)
 
static double ddCountPathsToNonZero (DdNode *N, st_table *table)
 
static void ddSupportStep (DdNode *f, int *support)
 
static void ddClearFlag (DdNode *f)
 
static int ddLeavesInt (DdNode *n)
 
static int ddPickArbitraryMinterms (DdManager *dd, DdNode *node, int nvars, int nminterms, char **string)
 
static void ddFindSupport (DdManager *dd, DdNode *f, int *SP)
 
double Cudd_CountMinterm (DdManager *manager, DdNode *node, int nvars)
 
DdGenCudd_FirstCube (DdManager *dd, DdNode *f, int **cube, CUDD_VALUE_TYPE *value)
 
int Cudd_NextCube (DdGen *gen, int **cube, CUDD_VALUE_TYPE *value)
 
DdGenCudd_FirstPrime (DdManager *dd, DdNode *l, DdNode *u, int **cube)
 
int Cudd_NextPrime (DdGen *gen, int **cube)
 
int Cudd_BddToCubeArray (DdManager *dd, DdNode *cube, int *array)
 
DdGenCudd_FirstNode (DdManager *dd, DdNode *f, DdNode **node)
 
int Cudd_NextNode (DdGen *gen, DdNode **node)
 
int Cudd_GenFree (DdGen *gen)
 
int Cudd_IsGenEmpty (DdGen *gen)
 
long Cudd_Random (void)
 
void Cudd_Srandom (long seed)
 
void Cudd_OutOfMem (long size)
 
int cuddCollectNodes (DdNode *f, st_table *visited)
 
DdNodePtrcuddNodeArray (DdNode *f, int *n)
 
static int ddWindow2 (DdManager *table, int low, int high)
 
static int ddWindowConv2 (DdManager *table, int low, int high)
 
static int ddPermuteWindow3 (DdManager *table, int x)
 
static int ddWindow3 (DdManager *table, int low, int high)
 
static int ddWindowConv3 (DdManager *table, int low, int high)
 
static int ddPermuteWindow4 (DdManager *table, int w)
 
static int ddWindow4 (DdManager *table, int low, int high)
 
static int ddWindowConv4 (DdManager *table, int low, int high)
 
int cuddWindowReorder (DdManager *table, int low, int high, Cudd_ReorderingType submethod)
 
DdNodecuddZddProduct (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddZddUnateProduct (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddZddWeakDiv (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddZddWeakDivF (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddZddDivide (DdManager *dd, DdNode *f, DdNode *g)
 
DdNodecuddZddDivideF (DdManager *dd, DdNode *f, DdNode *g)
 
int cuddZddGetCofactors3 (DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)
 
int cuddZddGetCofactors2 (DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0)
 
DdNodecuddZddComplement (DdManager *dd, DdNode *node)
 
int cuddZddGetPosVarIndex (DdManager *dd, int index)
 
int cuddZddGetNegVarIndex (DdManager *dd, int index)
 
int cuddZddGetPosVarLevel (DdManager *dd, int index)
 
int cuddZddGetNegVarLevel (DdManager *dd, int index)
 
static int zddTreeSiftingAux (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
 
static int zddReorderChildren (DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
 
static void zddFindNodeHiLo (DdManager *table, MtrNode *treenode, int *lower, int *upper)
 
static int zddUniqueCompareGroup (int *ptrX, int *ptrY)
 
static int zddGroupSifting (DdManager *table, int lower, int upper)
 
static int zddGroupSiftingAux (DdManager *table, int x, int xLow, int xHigh)
 
static int zddGroupSiftingUp (DdManager *table, int y, int xLow, Move **moves)
 
static int zddGroupSiftingDown (DdManager *table, int x, int xHigh, Move **moves)
 
static int zddGroupMove (DdManager *table, int x, int y, Move **moves)
 
static int zddGroupMoveBackward (DdManager *table, int x, int y)
 
static int zddGroupSiftingBackward (DdManager *table, Move *moves, int size)
 
static void zddMergeGroups (DdManager *table, MtrNode *treenode, int low, int high)
 
int cuddZddTreeSifting (DdManager *table, Cudd_ReorderingType method)
 
DdNodecuddZddIsop (DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)
 
DdNodecuddBddIsop (DdManager *dd, DdNode *L, DdNode *U)
 
DdNodecuddMakeBddFromZddCover (DdManager *dd, DdNode *node)
 
static int cuddZddLinearInPlace (DdManager *table, int x, int y)
 
static int cuddZddLinearAux (DdManager *table, int x, int xLow, int xHigh)
 
static MovecuddZddLinearUp (DdManager *table, int y, int xLow, Move *prevMoves)
 
static MovecuddZddLinearDown (DdManager *table, int x, int xHigh, Move *prevMoves)
 
static int cuddZddLinearBackward (DdManager *table, int size, Move *moves)
 
static MovecuddZddUndoMoves (DdManager *table, Move *moves)
 
int cuddZddLinearSifting (DdManager *table, int lower, int upper)
 
static MovezddSwapAny (DdManager *table, int x, int y)
 
static int cuddZddSiftingAux (DdManager *table, int x, int x_low, int x_high)
 
static MovecuddZddSiftingUp (DdManager *table, int x, int x_low, int initial_size)
 
static MovecuddZddSiftingDown (DdManager *table, int x, int x_high, int initial_size)
 
static int cuddZddSiftingBackward (DdManager *table, Move *moves, int size)
 
static void zddReorderPreprocess (DdManager *table)
 
static int zddReorderPostprocess (DdManager *table)
 
static int zddShuffle (DdManager *table, int *permutation)
 
static int zddSiftUp (DdManager *table, int x, int xLow)
 
static void zddFixTree (DdManager *table, MtrNode *treenode)
 
int Cudd_zddReduceHeap (DdManager *table, Cudd_ReorderingType heuristic, int minsize)
 
int cuddZddAlignToBdd (DdManager *table)
 
int cuddZddNextHigh (DdManager *table, int x)
 
int cuddZddNextLow (DdManager *table, int x)
 
int cuddZddUniqueCompare (int *ptr_x, int *ptr_y)
 
int cuddZddSwapInPlace (DdManager *table, int x, int y)
 
int cuddZddSwapping (DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)
 
int cuddZddSifting (DdManager *table, int lower, int upper)
 
static DdNodezdd_subset1_aux (DdManager *zdd, DdNode *P, DdNode *zvar)
 
static DdNodezdd_subset0_aux (DdManager *zdd, DdNode *P, DdNode *zvar)
 
static void zddVarToConst (DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty)
 
DdNodeCudd_zddDiffConst (DdManager *zdd, DdNode *P, DdNode *Q)
 
DdNodecuddZddIte (DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
 
DdNodecuddZddUnion (DdManager *zdd, DdNode *P, DdNode *Q)
 
DdNodecuddZddIntersect (DdManager *zdd, DdNode *P, DdNode *Q)
 
DdNodecuddZddDiff (DdManager *zdd, DdNode *P, DdNode *Q)
 
DdNodecuddZddChangeAux (DdManager *zdd, DdNode *P, DdNode *zvar)
 
DdNodecuddZddSubset1 (DdManager *dd, DdNode *P, int var)
 
DdNodecuddZddSubset0 (DdManager *dd, DdNode *P, int var)
 
static int cuddZddSymmSiftingAux (DdManager *table, int x, int x_low, int x_high)
 
static int cuddZddSymmSiftingConvAux (DdManager *table, int x, int x_low, int x_high)
 
static MovecuddZddSymmSifting_up (DdManager *table, int x, int x_low, int initial_size)
 
static MovecuddZddSymmSifting_down (DdManager *table, int x, int x_high, int initial_size)
 
static int cuddZddSymmSiftingBackward (DdManager *table, Move *moves, int size)
 
static int zdd_group_move (DdManager *table, int x, int y, Move **moves)
 
static int zdd_group_move_backward (DdManager *table, int x, int y)
 
static void cuddZddSymmSummary (DdManager *table, int lower, int upper, int *symvars, int *symgroups)
 
int cuddZddSymmCheck (DdManager *table, int x, int y)
 
int cuddZddSymmSifting (DdManager *table, int lower, int upper)
 
int cuddZddSymmSiftingConv (DdManager *table, int lower, int upper)
 

Variables

static char rcsid [] DD_UNUSED = "$Id: cuddAddIte.c,v 1.16 2012/02/05 01:07:18 fabio Exp $"
 
static int popsize
 
static int numvars
 
static int * storedd
 
static st_tablecomputed
 
static int * repeat
 
static int large
 
static int result
 
static int cross
 
static int * entry
 
int ddTotalNumberSwapping
 
static unsigned int originalSize
 
static DdNodeone
 
static DdNodezero
 
static DdNodebackground
 
static long cuddRand = 0
 
static long cuddRand2
 
static long shuffleSelect
 
static long shuffleTable [STAB_SIZE]
 
int zddTotalNumberSwapping
 
int * zdd_entry
 
static int zddTotalNumberLinearTr
 
static DdNodeempty
 

Macro Definition Documentation

◆ ABC

#define ABC   1

◆ ABCD

#define ABCD   1

◆ ABDC

#define ABDC   8

◆ ACB

#define ACB   6

◆ ACBD

#define ACBD   2

◆ ACDB

#define ACDB   4

◆ ADBC

#define ADBC   14

◆ ADCB

#define ADCB   9

◆ ALPHA

#define ALPHA   0.90

Definition at line 681 of file cuddInt.c.

◆ BAC

#define BAC   2

◆ BACD

#define BACD   7

◆ BADC

#define BADC   13

◆ bang

#define bang (   f)    ((Cudd_IsComplement(f)) ? '!' : ' ')

Definition at line 22152 of file cuddInt.c.

◆ BCA

#define BCA   3

◆ BCAD

#define BCAD   10

◆ BCDA

#define BCDA   16

◆ BDAC

#define BDAC   19

◆ BDCA

#define BDCA   21

◆ BETA

#define BETA   0.6

CFile***********************************************************************

FileName [cuddAnneal.c]

PackageName [cudd]

Synopsis [Reordering of DDs based on simulated annealing]

Description [Internal procedures included in this file:

Static procedures included in this file:

]

SeeAlso []

Author [Jae-Young Jang, Jorgen Sivesind]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 680 of file cuddInt.c.

◆ BPL [1/2]

#define BPL   32

CFile***********************************************************************

FileName [cuddInteract.c]

PackageName [cudd]

Synopsis [Functions to manipulate the variable interaction matrix.]

Description [Internal procedures included in this file:

Static procedures included in this file:

The interaction matrix tells whether two variables are both in the support of some function of the DD. The main use of the interaction matrix is in the in-place swapping. Indeed, if two variables do not interact, there is no arc connecting the two layers; therefore, the swap can be performed in constant time, without scanning the subtables. Another use of the interaction matrix is in the computation of the lower bounds for sifting. Finally, the interaction matrix can be used to speed up aggregation checks in symmetric and group sifting.

The computation of the interaction matrix is done with a series of depth-first searches. The searches start from those nodes that have only external references. The matrix is stored as a packed array of bits; since it is symmetric, only the upper triangle is kept in memory. As a final remark, we note that there may be variables that do interact, but that for a given variable order have no arc connecting their layers when they are adjacent. For instance, in ite(a,b,c) with the order a<b<c, b and c interact, but are not connected.]

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 12624 of file cuddInt.c.

◆ BPL [2/2]

#define BPL   32

CFile***********************************************************************

FileName [cuddInteract.c]

PackageName [cudd]

Synopsis [Functions to manipulate the variable interaction matrix.]

Description [Internal procedures included in this file:

Static procedures included in this file:

The interaction matrix tells whether two variables are both in the support of some function of the DD. The main use of the interaction matrix is in the in-place swapping. Indeed, if two variables do not interact, there is no arc connecting the two layers; therefore, the swap can be performed in constant time, without scanning the subtables. Another use of the interaction matrix is in the computation of the lower bounds for sifting. Finally, the interaction matrix can be used to speed up aggregation checks in symmetric and group sifting.

The computation of the interaction matrix is done with a series of depth-first searches. The searches start from those nodes that have only external references. The matrix is stored as a packed array of bits; since it is symmetric, only the upper triangle is kept in memory. As a final remark, we note that there may be variables that do interact, but that for a given variable order have no arc connecting their layers when they are adjacent. For instance, in ite(a,b,c) with the order a<b<c, b and c interact, but are not connected.]

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 12624 of file cuddInt.c.

◆ CAB

#define CAB   5

◆ CABD

#define CABD   3

◆ CADB

#define CADB   6

◆ CBA

#define CBA   4

◆ CBAD

#define CBAD   5

◆ CBDA

#define CBDA   11

◆ CDAB

#define CDAB   12

◆ CDBA

#define CDBA   17

◆ CUDD_INVERSE_TRANSFORM_MOVE [1/2]

#define CUDD_INVERSE_TRANSFORM_MOVE   2

Definition at line 28544 of file cuddInt.c.

◆ CUDD_INVERSE_TRANSFORM_MOVE [2/2]

#define CUDD_INVERSE_TRANSFORM_MOVE   2

Definition at line 28544 of file cuddInt.c.

◆ CUDD_LINEAR_TRANSFORM_MOVE [1/2]

#define CUDD_LINEAR_TRANSFORM_MOVE   1

Definition at line 28543 of file cuddInt.c.

◆ CUDD_LINEAR_TRANSFORM_MOVE [2/2]

#define CUDD_LINEAR_TRANSFORM_MOVE   1

Definition at line 28543 of file cuddInt.c.

◆ CUDD_SWAP_MOVE [1/2]

#define CUDD_SWAP_MOVE   0

CFile***********************************************************************

FileName [cuddLinear.c]

PackageName [cudd]

Synopsis [Functions for DD reduction by linear transformations.]

Description [ Internal procedures included in this module:

Static procedures included in this module:

]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

CFile***********************************************************************

FileName [cuddZddLin.c]

PackageName [cudd]

Synopsis [Procedures for dynamic variable ordering of ZDDs.]

Description [Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso [cuddLinear.c cuddZddReord.c]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 28542 of file cuddInt.c.

◆ CUDD_SWAP_MOVE [2/2]

#define CUDD_SWAP_MOVE   0

CFile***********************************************************************

FileName [cuddLinear.c]

PackageName [cudd]

Synopsis [Functions for DD reduction by linear transformations.]

Description [ Internal procedures included in this module:

Static procedures included in this module:

]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

CFile***********************************************************************

FileName [cuddZddLin.c]

PackageName [cudd]

Synopsis [Procedures for dynamic variable ordering of ZDDs.]

Description [Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso [cuddLinear.c cuddZddReord.c]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 28542 of file cuddInt.c.

◆ DABC

#define DABC   20

◆ DACB

#define DACB   15

◆ DBAC

#define DBAC   23

◆ DBCA

#define DBCA   24

◆ DCAB

#define DCAB   18

◆ DCBA

#define DCBA   22

◆ DD_BIGGY

#define DD_BIGGY   100000000

CFile***********************************************************************

FileName [cuddSat.c]

PackageName [cudd]

Synopsis [Functions for the solution of satisfiability related problems.]

Description [External procedures included in this file:

Internal procedures included in this module:

Static procedures included in this module:

]

Author [Seh-Woong Jeong, Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 16539 of file cuddInt.c.

◆ DD_LAZY_SIFT

#define DD_LAZY_SIFT   1

Definition at line 8392 of file cuddInt.c.

◆ DD_MAX_HASHTABLE_DENSITY

#define DD_MAX_HASHTABLE_DENSITY   2 /* tells when to resize a table */

CFile***********************************************************************

FileName [cuddLCache.c]

PackageName [cudd]

Synopsis [Functions for local caches.]

Description [Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 11244 of file cuddInt.c.

◆ DD_MAX_SUBTABLE_SPARSITY [1/2]

#define DD_MAX_SUBTABLE_SPARSITY   8

CFile***********************************************************************

FileName [cuddReorder.c]

PackageName [cudd]

Synopsis [Functions for dynamic variable reordering.]

Description [External procedures included in this file:

Internal procedures included in this module:

Static procedures included in this module:

]

Author [Shipra Panda, Bernard Plessier, Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

CFile***********************************************************************

FileName [cuddZddReord.c]

PackageName [cudd]

Synopsis [Procedures for dynamic variable ordering of ZDDs.]

Description [External procedures included in this module:

Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso []

Author [Hyong-Kyoon Shin, In-Ho Moon]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 29525 of file cuddInt.c.

◆ DD_MAX_SUBTABLE_SPARSITY [2/2]

#define DD_MAX_SUBTABLE_SPARSITY   8

CFile***********************************************************************

FileName [cuddReorder.c]

PackageName [cudd]

Synopsis [Functions for dynamic variable reordering.]

Description [External procedures included in this file:

Internal procedures included in this module:

Static procedures included in this module:

]

Author [Shipra Panda, Bernard Plessier, Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

CFile***********************************************************************

FileName [cuddZddReord.c]

PackageName [cudd]

Synopsis [Procedures for dynamic variable ordering of ZDDs.]

Description [External procedures included in this module:

Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso []

Author [Hyong-Kyoon Shin, In-Ho Moon]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 29525 of file cuddInt.c.

◆ DD_NORMAL_SIFT

#define DD_NORMAL_SIFT   0

CFile***********************************************************************

FileName [cuddGroup.c]

PackageName [cudd]

Synopsis [Functions for group sifting.]

Description [External procedures included in this file:

  • Cudd_MakeTreeNode()

Internal procedures included in this file:

Static procedures included in this module:

]

Author [Shipra Panda, Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 8391 of file cuddInt.c.

◆ DD_SIFT_DOWN

#define DD_SIFT_DOWN   0

Definition at line 8395 of file cuddInt.c.

◆ DD_SIFT_UP

#define DD_SIFT_UP   1

Definition at line 8396 of file cuddInt.c.

◆ ddLCHash1

#define ddLCHash1 (   f,
  shift 
)    (((unsigned)(f) * DD_P1) >> (shift))

Macro***********************************************************************

Synopsis [Computes hash function for keys of one operand.]

Description []

SideEffects [None]

SeeAlso [ddLCHash3 ddLCHash]

Definition at line 11283 of file cuddInt.c.

◆ ddLCHash2

#define ddLCHash2 (   f,
  g,
  shift 
)    ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift))

Macro***********************************************************************

Synopsis [Computes hash function for keys of two operands.]

Description []

SideEffects [None]

SeeAlso [ddLCHash3 ddLCHash]

Definition at line 11304 of file cuddInt.c.

◆ ddLCHash3

#define ddLCHash3 (   f,
  g,
  h,
  shift 
)    ddCHash2(f,g,h,shift)

Macro***********************************************************************

Synopsis [Computes hash function for keys of three operands.]

Description []

SideEffects [None]

SeeAlso [ddLCHash2 ddLCHash]

Definition at line 11320 of file cuddInt.c.

◆ EXC_PROB

#define EXC_PROB   0.4

Definition at line 682 of file cuddInt.c.

◆ JUMP_UP_PROB

#define JUMP_UP_PROB   0.36

Definition at line 683 of file cuddInt.c.

◆ LEQA1

#define LEQA1   40014

Definition at line 22114 of file cuddInt.c.

◆ LEQA2

#define LEQA2   40692

Definition at line 22118 of file cuddInt.c.

◆ LEQQ1

#define LEQQ1   53668

Definition at line 22115 of file cuddInt.c.

◆ LEQQ2

#define LEQQ2   52774

Definition at line 22119 of file cuddInt.c.

◆ LEQR1

#define LEQR1   12211

Definition at line 22116 of file cuddInt.c.

◆ LEQR2

#define LEQR2   3791

Definition at line 22120 of file cuddInt.c.

◆ LOGBPL [1/2]

#define LOGBPL   5

Definition at line 12625 of file cuddInt.c.

◆ LOGBPL [2/2]

#define LOGBPL   5

Definition at line 12625 of file cuddInt.c.

◆ MAXGEN_RATIO

#define MAXGEN_RATIO   15.0

Definition at line 684 of file cuddInt.c.

◆ MODULUS1

#define MODULUS1   2147483563

CFile***********************************************************************

FileName [cuddUtil.c]

PackageName [cudd]

Synopsis [Utility functions.]

Description [External procedures included in this module:

  • Cudd_PrintMinterm()
  • Cudd_bddPrintCover()
  • Cudd_PrintDebug()
  • Cudd_DagSize()
  • Cudd_EstimateCofactor()
  • Cudd_EstimateCofactorSimple()
  • Cudd_SharingSize()
  • Cudd_CountMinterm()
  • Cudd_EpdCountMinterm()
  • Cudd_CountPath()
  • Cudd_CountPathsToNonZero()
  • Cudd_SupportIndices()
  • Cudd_Support()
  • Cudd_SupportIndex()
  • Cudd_SupportSize()
  • Cudd_VectorSupportIndices()
  • Cudd_VectorSupport()
  • Cudd_VectorSupportIndex()
  • Cudd_VectorSupportSize()
  • Cudd_ClassifySupport()
  • Cudd_CountLeaves()
  • Cudd_bddPickOneCube()
  • Cudd_bddPickOneMinterm()
  • Cudd_bddPickArbitraryMinterms()
  • Cudd_SubsetWithMaskVars()
  • Cudd_FirstCube()
  • Cudd_NextCube()
  • Cudd_bddComputeCube()
  • Cudd_addComputeCube()
  • Cudd_FirstNode()
  • Cudd_NextNode()
  • Cudd_GenFree()
  • Cudd_IsGenEmpty()
  • Cudd_IndicesToCube()
  • Cudd_PrintVersion()
  • Cudd_AverageDistance()
  • Cudd_Random()
  • Cudd_Srandom()
  • Cudd_Density()

Internal procedures included in this module:

Static procedures included in this module:

]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 22113 of file cuddInt.c.

◆ MODULUS2

#define MODULUS2   2147483399

Definition at line 22117 of file cuddInt.c.

◆ MV_OOM

#define MV_OOM   (Move *)1

CFile***********************************************************************

FileName [cuddSymmetry.c]

PackageName [cudd]

Synopsis [Functions for symmetry-based variable reordering.]

Description [External procedures included in this file:

  • Cudd_SymmProfile()

Internal procedures included in this module:

Static procedures included in this module:

]

Author [Shipra Panda, Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 17842 of file cuddInt.c.

◆ STAB_DIV

#define STAB_DIV   (1 + (MODULUS1 - 1) / STAB_SIZE)

Definition at line 22122 of file cuddInt.c.

◆ STAB_SIZE

#define STAB_SIZE   64

Definition at line 22121 of file cuddInt.c.

◆ STOP_TEMP

#define STOP_TEMP   1.0

Definition at line 685 of file cuddInt.c.

◆ STOREDD

#define STOREDD (   i,
 
)    storedd[(i)*(numvars+1)+(j)]

Definition at line 7476 of file cuddInt.c.

◆ WEIGHT

#define WEIGHT (   weight,
  col 
)    ((weight) == NULL ? 1 : weight[col])

Definition at line 16568 of file cuddInt.c.

◆ ZDD_MV_OOM

#define ZDD_MV_OOM   (Move *)1

CFile***********************************************************************

FileName [cuddZddSymm.c]

PackageName [cudd]

Synopsis [Functions for symmetry-based ZDD variable reordering.]

Description [External procedures included in this module:

  • Cudd_zddSymmProfile()

Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso [cuddSymmetry.c]

Author [Hyong-Kyoon Shin, In-Ho Moon]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 32055 of file cuddInt.c.

Typedef Documentation

◆ cuddPathPair

typedef struct cuddPathPair cuddPathPair

◆ DD_CHKFP

typedef int(* DD_CHKFP) (DdManager *, int, int)

Definition at line 8409 of file cuddInt.c.

◆ hack

typedef union hack hack

CFile***********************************************************************

FileName [cuddTable.c]

PackageName [cudd]

Synopsis [Unique table management functions.]

Description [External procedures included in this module:

  • Cudd_Prime()
  • Cudd_Reserve()

Internal procedures included in this module:

Static procedures included in this module:

  • ddRehashZdd()
  • ddResizeTable()
  • cuddFindParent()
  • cuddOrderedInsert()
  • cuddOrderedThread()
  • cuddRotateLeft()
  • cuddRotateRight()
  • cuddDoRebalance()
  • cuddCheckCollisionOrdering()

]

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Function Documentation

◆ addMultiplicityGroups()

static int addMultiplicityGroups ( DdManager dd,
MtrNode treenode,
int  multiplicity,
char *  vmask,
char *  lmask 
)
static

Function********************************************************************

Synopsis [Adds multiplicity groups to a ZDD variable group tree.]

Description [Adds multiplicity groups to a ZDD variable group tree. Returns 1 if successful; 0 otherwise. This function creates the groups for set of ZDD variables (whose cardinality is given by parameter multiplicity) that are created for each BDD variable in Cudd_zddVarsFromBddVars. The crux of the matter is to determine the index each new group. (The index of the first variable in the group.) We first build all the groups for the children of a node, and then deal with the ZDD variables that are directly attached to the node. The problem for these is that the tree itself does not provide information on their position inside the group. While we deal with the children of the node, therefore, we keep track of all the positions they occupy. The remaining positions in the tree can be freely used. Also, we keep track of all the variables placed in the children. All the remaining variables are directly attached to the group. We can then place any pair of variables not yet grouped in any pair of available positions in the node.]

SideEffects [Changes the variable group tree.]

SeeAlso [Cudd_zddVarsFromBddVars]

Definition at line 2169 of file cuddInt.c.

2175 {
2176  int startV, stopV, startL;
2177  int i, j;
2178  MtrNode *auxnode = treenode;
2179 
2180  while (auxnode != NULL) {
2181  if (auxnode->child != NULL) {
2182  addMultiplicityGroups(dd,auxnode->child,multiplicity,vmask,lmask);
2183  }
2184  /* Build remaining groups. */
2185  startV = dd->permZ[auxnode->index] / multiplicity;
2186  startL = auxnode->low / multiplicity;
2187  stopV = startV + auxnode->size / multiplicity;
2188  /* Walk down vmask starting at startV and build missing groups. */
2189  for (i = startV, j = startL; i < stopV; i++) {
2190  if (vmask[i] == 0) {
2191  MtrNode *node;
2192  while (lmask[j] == 1) j++;
2193  node = Mtr_MakeGroup(auxnode, j * multiplicity, multiplicity,
2194  MTR_FIXED);
2195  if (node == NULL) {
2196  return(0);
2197  }
2198  node->index = dd->invpermZ[i * multiplicity];
2199  vmask[i] = 1;
2200  lmask[j] = 1;
2201  }
2202  }
2203  auxnode = auxnode->younger;
2204  }
2205  return(1);
2206 
2207 } /* end of addMultiplicityGroups */
MtrHalfWord size
Definition: mtr.h:129
int * invpermZ
Definition: cuddInt.h:372
#define MTR_FIXED
Definition: mtr.h:97
int * permZ
Definition: cuddInt.h:370
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord index
Definition: mtr.h:130
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
static int addMultiplicityGroups(DdManager *dd, MtrNode *treenode, int multiplicity, char *vmask, char *lmask)
Definition: cuddInt.c:2169
MtrNode * Mtr_MakeGroup(MtrNode *root, unsigned int low, unsigned int high, unsigned int flags)
Definition: mtr.c:446
struct MtrNode * child
Definition: mtr.h:132

◆ addVarToConst()

static void addVarToConst ( DdNode f,
DdNode **  gp,
DdNode **  hp,
DdNode one,
DdNode zero 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Replaces variables with constants if possible (part of canonical form).]

Description []

SideEffects [None]

Definition at line 590 of file cuddInt.c.

596 {
597  DdNode *g = *gp;
598  DdNode *h = *hp;
599 
600  if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
601  *gp = one;
602  }
603 
604  if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
605  *hp = zero;
606  }
607 
608 } /* end of addVarToConst */
Definition: cudd.h:264
static DdNode * one
Definition: cuddInt.c:16562
static DdNode * zero
Definition: cuddInt.c:16562

◆ array_compare()

static int array_compare ( const char *  array1,
const char *  array2 
)
static

Function********************************************************************

Synopsis [Comparison function for the computed table.]

Description [Comparison function for the computed table. Returns 0 if the two arrays are equal; 1 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 8050 of file cuddInt.c.

8053 {
8054  int i;
8055  int *intarray1, *intarray2;
8056 
8057  intarray1 = (int *) array1;
8058  intarray2 = (int *) array2;
8059 
8060  for (i = 0; i < numvars; i++) {
8061  if (intarray1[i] != intarray2[i]) return(1);
8062  }
8063  return(0);
8064 
8065 } /* end of array_compare */
static int numvars
Definition: cuddInt.c:7452

◆ array_hash()

static int array_hash ( char *  array,
int  modulus 
)
static

Function********************************************************************

Synopsis [Hash function for the computed table.]

Description [Hash function for the computed table. Returns the bucket number.]

SideEffects [None]

SeeAlso []

Definition at line 8018 of file cuddInt.c.

8021 {
8022  int val = 0;
8023  int i;
8024  int *intarray;
8025 
8026  intarray = (int *) array;
8027 
8028  for (i = 0; i < numvars; i++) {
8029  val = val * 997 + intarray[i];
8030  }
8031 
8032  return ((val < 0) ? -val : val) % modulus;
8033 
8034 } /* end of array_hash */
static int numvars
Definition: cuddInt.c:7452

◆ bddCheckPositiveCube()

static int bddCheckPositiveCube ( DdManager manager,
DdNode cube 
)
static

CFile***********************************************************************

FileName [cuddBddAbs.c]

PackageName [cudd]

Synopsis [Quantification functions for BDDs.]

Description [External procedures included in this module:

Internal procedures included in this module:

Static procedures included in this module:

]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart

Function********************************************************************

Synopsis [Checks whether cube is an BDD representing the product of positive literals.]

Description [Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 2791 of file cuddInt.c.

2794 {
2795  if (Cudd_IsComplement(cube)) return(0);
2796  if (cube == DD_ONE(manager)) return(1);
2797  if (cuddIsConstant(cube)) return(0);
2798  if (cuddE(cube) == Cudd_Not(DD_ONE(manager))) {
2799  return(bddCheckPositiveCube(manager, cuddT(cube)));
2800  }
2801  return(0);
2802 
2803 } /* end of bddCheckPositiveCube */
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define cuddIsConstant(node)
Definition: cuddInt.h:593
static int bddCheckPositiveCube(DdManager *manager, DdNode *cube)
Definition: cuddInt.c:2791
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ bddFixTree()

static void bddFixTree ( DdManager table,
MtrNode treenode 
)
static

Function********************************************************************

Synopsis [Fixes the BDD variable group tree after a shuffle.]

Description [Fixes the BDD variable group tree after a shuffle. Assumes that the order of the variables in a terminal node has not been changed.]

SideEffects [Changes the BDD variable group tree.]

SeeAlso []

Definition at line 16331 of file cuddInt.c.

16334 {
16335  if (treenode == NULL) return;
16336  treenode->low = ((int) treenode->index < table->size) ?
16337  table->perm[treenode->index] : treenode->index;
16338  if (treenode->child != NULL) {
16339  bddFixTree(table, treenode->child);
16340  }
16341  if (treenode->younger != NULL)
16342  bddFixTree(table, treenode->younger);
16343  if (treenode->parent != NULL && treenode->low < treenode->parent->low) {
16344  treenode->parent->low = treenode->low;
16345  treenode->parent->index = treenode->index;
16346  }
16347  return;
16348 
16349 } /* end of bddFixTree */
int size
Definition: cuddInt.h:345
struct MtrNode * parent
Definition: mtr.h:131
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord index
Definition: mtr.h:130
static void bddFixTree(DdManager *table, MtrNode *treenode)
Definition: cuddInt.c:16331
MtrHalfWord low
Definition: mtr.h:128
struct MtrNode * child
Definition: mtr.h:132
int * perm
Definition: cuddInt.h:369

◆ bddVarToCanonical()

static int bddVarToCanonical ( DdManager dd,
DdNode **  fp,
DdNode **  gp,
DdNode **  hp,
unsigned int *  topfp,
unsigned int *  topgp,
unsigned int *  tophp 
)
static

Function********************************************************************

Synopsis [Picks unique member from equiv expressions.]

Description [Reduces 2 variable expressions to canonical form.]

SideEffects [None]

SeeAlso [bddVarToConst bddVarToCanonicalSimple]

Definition at line 3917 of file cuddInt.c.

3925 {
3926  register DdNode *F, *G, *H, *r, *f, *g, *h;
3927  register unsigned int topf, topg, toph;
3928  DdNode *one = dd->one;
3929  int comple, change;
3930 
3931  f = *fp;
3932  g = *gp;
3933  h = *hp;
3934  F = Cudd_Regular(f);
3935  G = Cudd_Regular(g);
3936  H = Cudd_Regular(h);
3937  topf = cuddI(dd,F->index);
3938  topg = cuddI(dd,G->index);
3939  toph = cuddI(dd,H->index);
3940 
3941  change = 0;
3942 
3943  if (G == one) { /* ITE(F,c,H) */
3944  if ((topf > toph) || (topf == toph && f > h)) {
3945  r = h;
3946  h = f;
3947  f = r; /* ITE(F,1,H) = ITE(H,1,F) */
3948  if (g != one) { /* g == zero */
3949  f = Cudd_Not(f); /* ITE(F,0,H) = ITE(!H,0,!F) */
3950  h = Cudd_Not(h);
3951  }
3952  change = 1;
3953  }
3954  } else if (H == one) { /* ITE(F,G,c) */
3955  if ((topf > topg) || (topf == topg && f > g)) {
3956  r = g;
3957  g = f;
3958  f = r; /* ITE(F,G,0) = ITE(G,F,0) */
3959  if (h == one) {
3960  f = Cudd_Not(f); /* ITE(F,G,1) = ITE(!G,!F,1) */
3961  g = Cudd_Not(g);
3962  }
3963  change = 1;
3964  }
3965  } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = ITE(G,F,!F) */
3966  if ((topf > topg) || (topf == topg && f > g)) {
3967  r = f;
3968  f = g;
3969  g = r;
3970  h = Cudd_Not(r);
3971  change = 1;
3972  }
3973  }
3974  /* adjust pointers so that the first 2 arguments to ITE are regular */
3975  if (Cudd_IsComplement(f) != 0) { /* ITE(!F,G,H) = ITE(F,H,G) */
3976  f = Cudd_Not(f);
3977  r = g;
3978  g = h;
3979  h = r;
3980  change = 1;
3981  }
3982  comple = 0;
3983  if (Cudd_IsComplement(g) != 0) { /* ITE(F,!G,H) = !ITE(F,G,!H) */
3984  g = Cudd_Not(g);
3985  h = Cudd_Not(h);
3986  change = 1;
3987  comple = 1;
3988  }
3989  if (change != 0) {
3990  *fp = f;
3991  *gp = g;
3992  *hp = h;
3993  }
3994  *topfp = cuddI(dd,f->index);
3995  *topgp = cuddI(dd,g->index);
3996  *tophp = cuddI(dd,Cudd_Regular(h)->index);
3997 
3998  return(comple);
3999 
4000 } /* end of bddVarToCanonical */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define cuddI(dd, index)
Definition: cuddInt.h:659
DdHalfWord index
Definition: cudd.h:265
DdNode * one
Definition: cuddInt.h:329

◆ bddVarToCanonicalSimple()

static int bddVarToCanonicalSimple ( DdManager dd,
DdNode **  fp,
DdNode **  gp,
DdNode **  hp,
unsigned int *  topfp,
unsigned int *  topgp,
unsigned int *  tophp 
)
static

Function********************************************************************

Synopsis [Picks unique member from equiv expressions.]

Description [Makes sure the first two pointers are regular. This mat require the complementation of the result, which is signaled by returning 1 instead of 0. This function is simpler than the general case because it assumes that no two arguments are the same or complementary, and no argument is constant.]

SideEffects [None]

SeeAlso [bddVarToConst bddVarToCanonical]

Definition at line 4019 of file cuddInt.c.

4027 {
4028  register DdNode *r, *f, *g, *h;
4029  int comple, change;
4030 
4031  f = *fp;
4032  g = *gp;
4033  h = *hp;
4034 
4035  change = 0;
4036 
4037  /* adjust pointers so that the first 2 arguments to ITE are regular */
4038  if (Cudd_IsComplement(f)) { /* ITE(!F,G,H) = ITE(F,H,G) */
4039  f = Cudd_Not(f);
4040  r = g;
4041  g = h;
4042  h = r;
4043  change = 1;
4044  }
4045  comple = 0;
4046  if (Cudd_IsComplement(g)) { /* ITE(F,!G,H) = !ITE(F,G,!H) */
4047  g = Cudd_Not(g);
4048  h = Cudd_Not(h);
4049  change = 1;
4050  comple = 1;
4051  }
4052  if (change) {
4053  *fp = f;
4054  *gp = g;
4055  *hp = h;
4056  }
4057 
4058  /* Here we can skip the use of cuddI, because the operands are known
4059  ** to be non-constant.
4060  */
4061  *topfp = dd->perm[f->index];
4062  *topgp = dd->perm[g->index];
4063  *tophp = dd->perm[Cudd_Regular(h)->index];
4064 
4065  return(comple);
4066 
4067 } /* end of bddVarToCanonicalSimple */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_Regular(node)
Definition: cudd.h:373
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdHalfWord index
Definition: cudd.h:265
int * perm
Definition: cuddInt.h:369

◆ bddVarToConst()

static void bddVarToConst ( DdNode f,
DdNode **  gp,
DdNode **  hp,
DdNode one 
)
static

CFile***********************************************************************

FileName [cuddBddIte.c]

PackageName [cudd]

Synopsis [BDD ITE function and satellites.]

Description [External procedures included in this module:

Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart

Function********************************************************************

Synopsis [Replaces variables with constants if possible.]

Description [This function performs part of the transformation to standard form by replacing variables with constants if possible.]

SideEffects [None]

SeeAlso [bddVarToCanonical bddVarToCanonicalSimple]

Definition at line 3882 of file cuddInt.c.

3887 {
3888  DdNode *g = *gp;
3889  DdNode *h = *hp;
3890 
3891  if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
3892  *gp = one;
3893  } else if (f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */
3894  *gp = Cudd_Not(one);
3895  }
3896  if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
3897  *hp = Cudd_Not(one);
3898  } else if (f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */
3899  *hp = one;
3900  }
3901 
3902 } /* end of bddVarToConst */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562

◆ build_dd()

static int build_dd ( DdManager table,
int  num,
int  lower,
int  upper 
)
static

Function********************************************************************

Synopsis [Builds a DD from a given order.]

Description [Builds a DD from a given order. This procedure also sifts the final order and inserts into the array the size in nodes of the result. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 7897 of file cuddInt.c.

7902 {
7903  int i,j; /* loop vars */
7904  int position;
7905  int index;
7906  int limit; /* how large the DD for this order can grow */
7907  int size;
7908 
7909  /* Check the computed table. If the order already exists, it
7910  ** suffices to copy the size from the existing entry.
7911  */
7912  if (computed && st_lookup_int(computed,(char *)&STOREDD(num,0),&index)) {
7913  STOREDD(num,numvars) = STOREDD(index,numvars);
7914 #ifdef DD_STATS
7915  (void) fprintf(table->out,"\nCache hit for index %d", index);
7916 #endif
7917  return(1);
7918  }
7919 
7920  /* Stop if the DD grows 20 times larges than the reference size. */
7921  limit = 20 * STOREDD(0,numvars);
7922 
7923  /* Sift up the variables so as to build the desired permutation.
7924  ** First the variable that has to be on top is sifted to the top.
7925  ** Then the variable that has to occupy the secon position is sifted
7926  ** up to the second position, and so on.
7927  */
7928  for (j = 0; j < numvars; j++) {
7929  i = STOREDD(num,j);
7930  position = table->perm[i];
7931  result = sift_up(table,position,j+lower);
7932  if (!result) return(0);
7933  size = table->keys - table->isolated;
7934  if (size > limit) break;
7935  }
7936 
7937  /* Sift the DD just built. */
7938 #ifdef DD_STATS
7939  (void) fprintf(table->out,"\n");
7940 #endif
7941  result = cuddSifting(table,lower,upper);
7942  if (!result) return(0);
7943 
7944  /* Copy order and size to table. */
7945  for (j = 0; j < numvars; j++) {
7946  STOREDD(num,j) = table->invperm[lower+j];
7947  }
7948  STOREDD(num,numvars) = table->keys - table->isolated; /* size of new DD */
7949  return(1);
7950 
7951 } /* end of build_dd */
int st_lookup_int(st_table *, void *, int *)
Definition: st.c:307
static int numvars
Definition: cuddInt.c:7452
int cuddSifting(DdManager *table, int lower, int upper)
Definition: cuddInt.c:14824
#define STOREDD(i, j)
Definition: cuddInt.c:7476
static int sift_up(DdManager *table, int x, int x_low)
Definition: cuddInt.c:7861
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
static st_table * computed
Definition: cuddInt.c:7462
static int result
Definition: cuddInt.c:7466
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int * perm
Definition: cuddInt.h:369

◆ checkSymmInfo()

static int checkSymmInfo ( DdManager table,
DdHalfWord symmInfo,
int  index,
int  level 
)
static

Function********************************************************************

Synopsis [Check symmetry condition.]

Description [Returns 1 if a variable is the one with the highest index among those belonging to a symmetry group that are in the top part of the BDD. The top part is given by level.]

SideEffects [None]

SeeAlso [initSymmInfo]

Definition at line 7329 of file cuddInt.c.

7334 {
7335  int i;
7336 
7337  i = symmInfo[index];
7338  while (i != index) {
7339  if (index < i && table->perm[i] <= level)
7340  return(0);
7341  i = symmInfo[i];
7342  }
7343  return(1);
7344 
7345 } /* end of checkSymmInfo */

◆ computeLB()

static int computeLB ( DdManager table,
DdHalfWord order,
int  roots,
int  cost,
int  lower,
int  upper,
int  level 
)
static

Function********************************************************************

Synopsis [Computes a lower bound on the size of a BDD.]

Description [Computes a lower bound on the size of a BDD from the following factors:

  • size of the lower part of it;
  • size of the part of the upper part not subjected to reordering;
  • number of roots in the part of the BDD subjected to reordering;
  • variable in the support of the roots in the upper part of the BDD subjected to reordering.

    SideEffects [None]

    SeeAlso []

Definition at line 7134 of file cuddInt.c.

7143 {
7144  int i;
7145  int lb = cost;
7146  int lb1 = 0;
7147  int lb2;
7148  int support;
7149  DdHalfWord ref;
7150 
7151  /* The levels not involved in reordering are not going to change.
7152  ** Add their sizes to the lower bound.
7153  */
7154  for (i = 0; i < lower; i++) {
7155  lb += getLevelKeys(table,i);
7156  }
7157  /* If a variable is in the support, then there is going
7158  ** to be at least one node labeled by that variable.
7159  */
7160  for (i = lower; i <= lower+level; i++) {
7161  support = table->subtables[i].keys > 1 ||
7162  table->vars[order[i-lower]]->ref > 1;
7163  lb1 += support;
7164  }
7165 
7166  /* Estimate the number of nodes required to connect the roots to
7167  ** the nodes in the bottom part. */
7168  if (lower+level+1 < table->size) {
7169  if (lower+level < upper)
7170  ref = table->vars[order[level+1]]->ref;
7171  else
7172  ref = table->vars[table->invperm[upper+1]]->ref;
7173  lb2 = table->subtables[lower+level+1].keys -
7174  (ref > (DdHalfWord) 1) - roots;
7175  } else {
7176  lb2 = 0;
7177  }
7178 
7179  lb += lb1 > lb2 ? lb1 : lb2;
7180 
7181  return(lb);
7182 
7183 } /* end of computeLB */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
unsigned short DdHalfWord
Definition: cudd.h:253
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
static int getLevelKeys(DdManager *table, int l)
Definition: cuddInt.c:6830
DdNode ** vars
Definition: cuddInt.h:373
int * invperm
Definition: cuddInt.h:371

◆ copyOrder()

static void copyOrder ( DdManager table,
int *  array,
int  lower,
int  upper 
)
static

Function********************************************************************

Synopsis [Copies the current variable order to array.]

Description [Copies the current variable order to array. At the same time inverts the permutation.]

SideEffects [None]

SeeAlso []

Definition at line 1365 of file cuddInt.c.

1370 {
1371  int i;
1372  int nvars;
1373 
1374  nvars = upper - lower + 1;
1375  for (i = 0; i < nvars; i++) {
1376  array[i] = table->invperm[i+lower];
1377  }
1378 
1379 } /* end of copyOrder */
int * invperm
Definition: cuddInt.h:371

◆ Cudd_addCmpl()

DdNode* Cudd_addCmpl ( DdManager dd,
DdNode f 
)

Function********************************************************************

Synopsis [Computes the complement of an ADD a la C language.]

Description [Computes the complement of an ADD a la C language: The complement of 0 is 1 and the complement of everything else is 0. Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addNegate]

Definition at line 312 of file cuddInt.c.

315 {
316  DdNode *res;
317 
318  do {
319  dd->reordered = 0;
320  res = cuddAddCmplRecur(dd,f);
321  } while (dd->reordered == 1);
322  return(res);
323 
324 } /* end of Cudd_addCmpl */
Definition: cudd.h:264
int reordered
Definition: cuddInt.h:392
DdNode * cuddAddCmplRecur(DdManager *dd, DdNode *f)
Definition: cuddInt.c:527

◆ Cudd_addEvalConst()

DdNode* Cudd_addEvalConst ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Checks whether ADD g is constant whenever ADD f is 1.]

Description [Checks whether ADD g is constant whenever ADD f is 1. f must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may or may not be constant) or DD_NON_CONSTANT. If f is identically 0, the check is assumed to be successful, and the background value is returned. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_addIteConstant Cudd_addLeq]

Definition at line 225 of file cuddInt.c.

229 {
230  DdNode *zero;
231  DdNode *Fv,*Fnv,*Gv,*Gnv,*r,*t,*e;
232  unsigned int topf,topg;
233 
234 #ifdef DD_DEBUG
236 #endif
237 
238  statLine(dd);
239  /* Terminal cases. */
240  if (f == DD_ONE(dd) || cuddIsConstant(g)) {
241  return(g);
242  }
243  if (f == (zero = DD_ZERO(dd))) {
244  return(dd->background);
245  }
246 
247 #ifdef DD_DEBUG
248  assert(!cuddIsConstant(f));
249 #endif
250  /* From now on, f and g are known not to be constants. */
251 
252  topf = cuddI(dd,f->index);
253  topg = cuddI(dd,g->index);
254 
255  /* Check cache. */
257  if (r != NULL) {
258  return(r);
259  }
260 
261  /* Compute cofactors. */
262  if (topf <= topg) {
263  Fv = cuddT(f); Fnv = cuddE(f);
264  } else {
265  Fv = Fnv = f;
266  }
267  if (topg <= topf) {
268  Gv = cuddT(g); Gnv = cuddE(g);
269  } else {
270  Gv = Gnv = g;
271  }
272 
273  /* Recursive step. */
274  if (Fv != zero) {
275  t = Cudd_addEvalConst(dd,Fv,Gv);
276  if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) {
278  return(DD_NON_CONSTANT);
279  }
280  if (Fnv != zero) {
281  e = Cudd_addEvalConst(dd,Fnv,Gnv);
282  if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) {
284  return(DD_NON_CONSTANT);
285  }
286  }
288  return(t);
289  } else { /* Fnv must be != zero */
290  e = Cudd_addEvalConst(dd,Fnv,Gnv);
291  cuddCacheInsert2(dd, Cudd_addEvalConst, f, g, e);
292  return(e);
293  }
294 
295 } /* end of Cudd_addEvalConst */
DdNode * cuddConstantLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:4756
Definition: cudd.h:264
#define assert(ex)
Definition: util.h:141
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define DD_ADD_EVAL_CONST_TAG
Definition: cuddInt.h:186
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * Cudd_addEvalConst(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:225
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
DdNode * background
Definition: cuddInt.h:333
#define DD_NON_CONSTANT
Definition: cuddInt.h:124
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ Cudd_addIteConstant()

DdNode* Cudd_addIteConstant ( DdManager dd,
DdNode f,
DdNode g,
DdNode h 
)

AutomaticEnd Function********************************************************************

Synopsis [Implements ITEconstant for ADDs.]

Description [Implements ITEconstant for ADDs. f must be a 0-1 ADD. Returns a pointer to the resulting ADD (which may or may not be constant) or DD_NON_CONSTANT. No new nodes are created. This function can be used, for instance, to check that g has a constant value (specified by h) whenever f is 1. If the constant value is unknown, then one should use Cudd_addEvalConst.]

SideEffects [None]

SeeAlso [Cudd_addIte Cudd_addEvalConst Cudd_bddIteConstant]

Definition at line 128 of file cuddInt.c.

133 {
134  DdNode *one,*zero;
135  DdNode *Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*r,*t,*e;
136  unsigned int topf,topg,toph,v;
137 
138  statLine(dd);
139  /* Trivial cases. */
140  if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */
141  return(g);
142  }
143  if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
144  return(h);
145  }
146 
147  /* From now on, f is known not to be a constant. */
148  addVarToConst(f,&g,&h,one,zero);
149 
150  /* Check remaining one variable cases. */
151  if (g == h) { /* ITE(F,G,G) = G */
152  return(g);
153  }
154  if (cuddIsConstant(g) && cuddIsConstant(h)) {
155  return(DD_NON_CONSTANT);
156  }
157 
158  topf = cuddI(dd,f->index);
159  topg = cuddI(dd,g->index);
160  toph = cuddI(dd,h->index);
161  v = ddMin(topg,toph);
162 
163  /* ITE(F,G,H) = (x,G,H) (non constant) if F = (x,1,0), x < top(G,H). */
164  if (topf < v && cuddIsConstant(cuddT(f)) && cuddIsConstant(cuddE(f))) {
165  return(DD_NON_CONSTANT);
166  }
167 
168  /* Check cache. */
170  if (r != NULL) {
171  return(r);
172  }
173 
174  /* Compute cofactors. */
175  if (topf <= v) {
176  v = ddMin(topf,v); /* v = top_var(F,G,H) */
177  Fv = cuddT(f); Fnv = cuddE(f);
178  } else {
179  Fv = Fnv = f;
180  }
181  if (topg == v) {
182  Gv = cuddT(g); Gnv = cuddE(g);
183  } else {
184  Gv = Gnv = g;
185  }
186  if (toph == v) {
187  Hv = cuddT(h); Hnv = cuddE(h);
188  } else {
189  Hv = Hnv = h;
190  }
191 
192  /* Recursive step. */
193  t = Cudd_addIteConstant(dd,Fv,Gv,Hv);
194  if (t == DD_NON_CONSTANT || !cuddIsConstant(t)) {
196  return(DD_NON_CONSTANT);
197  }
198  e = Cudd_addIteConstant(dd,Fnv,Gnv,Hnv);
199  if (e == DD_NON_CONSTANT || !cuddIsConstant(e) || t != e) {
201  return(DD_NON_CONSTANT);
202  }
203  cuddCacheInsert(dd, DD_ADD_ITE_CONSTANT_TAG, f, g, h, t);
204  return(t);
205 
206 } /* end of Cudd_addIteConstant */
DdNode * cuddConstantLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:4756
DdNode * Cudd_addIteConstant(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:128
Definition: cudd.h:264
static DdNode * one
Definition: cuddInt.c:16562
#define DD_ADD_ITE_CONSTANT_TAG
Definition: cuddInt.h:185
static void addVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero)
Definition: cuddInt.c:590
#define statLine(dd)
Definition: cuddInt.h:990
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddInt.c:4283
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_NON_CONSTANT
Definition: cuddInt.h:124
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ Cudd_addLeq()

int Cudd_addLeq ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Determines whether f is less than or equal to g.]

Description [Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are created. This procedure works for arbitrary ADDs. For 0-1 ADDs Cudd_addEvalConst is more efficient.]

SideEffects [None]

SeeAlso [Cudd_addIteConstant Cudd_addEvalConst Cudd_bddLeq]

Definition at line 341 of file cuddInt.c.

345 {
346  DdNode *tmp, *fv, *fvn, *gv, *gvn;
347  unsigned int topf, topg, res;
348 
349  /* Terminal cases. */
350  if (f == g) return(1);
351 
352  statLine(dd);
353  if (cuddIsConstant(f)) {
354  if (cuddIsConstant(g)) return(cuddV(f) <= cuddV(g));
355  if (f == DD_MINUS_INFINITY(dd)) return(1);
356  if (f == DD_PLUS_INFINITY(dd)) return(0); /* since f != g */
357  }
358  if (g == DD_PLUS_INFINITY(dd)) return(1);
359  if (g == DD_MINUS_INFINITY(dd)) return(0); /* since f != g */
360 
361  /* Check cache. */
362  tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g);
363  if (tmp != NULL) {
364  return(tmp == DD_ONE(dd));
365  }
366 
367  /* Compute cofactors. One of f and g is not constant. */
368  topf = cuddI(dd,f->index);
369  topg = cuddI(dd,g->index);
370  if (topf <= topg) {
371  fv = cuddT(f); fvn = cuddE(f);
372  } else {
373  fv = fvn = f;
374  }
375  if (topg <= topf) {
376  gv = cuddT(g); gvn = cuddE(g);
377  } else {
378  gv = gvn = g;
379  }
380 
381  res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv);
382 
383  /* Store result in cache and return. */
385  Cudd_NotCond(DD_ONE(dd),res==0));
386  return(res);
387 
388 } /* end of Cudd_addLeq */
Definition: cudd.h:264
#define statLine(dd)
Definition: cuddInt.h:990
#define DD_MINUS_INFINITY(dd)
Definition: cuddInt.h:908
#define cuddV(node)
Definition: cuddInt.h:641
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:297
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:359
#define DD_PLUS_INFINITY(dd)
Definition: cuddInt.h:894
int Cudd_addLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:341
#define DD_ONE(dd)
Definition: cuddInt.h:864
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329

◆ Cudd_bddAnd()

DdNode* Cudd_bddAnd ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Computes the conjunction of two BDDs f and g.]

Description [Computes the conjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAndAbstract Cudd_bddIntersect Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]

Definition at line 3114 of file cuddInt.c.

3118 {
3119  DdNode *res;
3120 
3121  do {
3122  dd->reordered = 0;
3123  res = cuddBddAndRecur(dd,f,g);
3124  } while (dd->reordered == 1);
3125  return(res);
3126 
3127 } /* end of Cudd_bddAnd */
Definition: cudd.h:264
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633

◆ Cudd_bddAndLimit()

DdNode* Cudd_bddAndLimit ( DdManager dd,
DdNode f,
DdNode g,
unsigned int  limit 
)

Function********************************************************************

Synopsis [Computes the conjunction of two BDDs f and g. Returns NULL if too many nodes are required.]

Description [Computes the conjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up or more new nodes than limit are required.]

SideEffects [None]

SeeAlso [Cudd_bddAnd]

Definition at line 3146 of file cuddInt.c.

3151 {
3152  DdNode *res;
3153  unsigned int saveLimit = dd->maxLive;
3154 
3155  dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit;
3156  do {
3157  dd->reordered = 0;
3158  res = cuddBddAndRecur(dd,f,g);
3159  } while (dd->reordered == 1);
3160  dd->maxLive = saveLimit;
3161  return(res);
3162 
3163 } /* end of Cudd_bddAndLimit */
Definition: cudd.h:264
unsigned int deadZ
Definition: cuddInt.h:356
int reordered
Definition: cuddInt.h:392
unsigned int dead
Definition: cuddInt.h:355
unsigned int maxLive
Definition: cuddInt.h:357
unsigned int keys
Definition: cuddInt.h:353
unsigned int keysZ
Definition: cuddInt.h:354
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633

◆ Cudd_bddExistAbstract()

DdNode* Cudd_bddExistAbstract ( DdManager manager,
DdNode f,
DdNode cube 
)

AutomaticEnd Function********************************************************************

Synopsis [Existentially abstracts all the variables in cube from f.]

Description [Existentially abstracts all the variables in cube from f. Returns the abstracted BDD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddUnivAbstract Cudd_addExistAbstract]

Definition at line 2331 of file cuddInt.c.

2335 {
2336  DdNode *res;
2337 
2338  if (bddCheckPositiveCube(manager, cube) == 0) {
2339  (void) fprintf(manager->err,
2340  "Error: Can only abstract positive cubes\n");
2341  manager->errorCode = CUDD_INVALID_ARG;
2342  return(NULL);
2343  }
2344 
2345  do {
2346  manager->reordered = 0;
2347  res = cuddBddExistAbstractRecur(manager, f, cube);
2348  } while (manager->reordered == 1);
2349 
2350  return(res);
2351 
2352 } /* end of Cudd_bddExistAbstract */
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddInt.c:2437
Definition: cudd.h:264
FILE * err
Definition: cuddInt.h:424
int reordered
Definition: cuddInt.h:392
static int bddCheckPositiveCube(DdManager *manager, DdNode *cube)
Definition: cuddInt.c:2791
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ Cudd_bddIntersect()

DdNode* Cudd_bddIntersect ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Returns a function included in the intersection of f and g.]

Description [Computes a function included in the intersection of f and g. (That is, a witness that the intersection is not empty.) Cudd_bddIntersect tries to build as few new nodes as possible. If the only result of interest is whether f and g intersect, Cudd_bddLeq should be used instead.]

SideEffects [None]

SeeAlso [Cudd_bddLeq Cudd_bddIteConstant]

Definition at line 3082 of file cuddInt.c.

3086 {
3087  DdNode *res;
3088 
3089  do {
3090  dd->reordered = 0;
3091  res = cuddBddIntersectRecur(dd,f,g);
3092  } while (dd->reordered == 1);
3093 
3094  return(res);
3095 
3096 } /* end of Cudd_bddIntersect */
Definition: cudd.h:264
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddIntersectRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3518

◆ Cudd_bddIsVarToBeGrouped()

int Cudd_bddIsVarToBeGrouped ( DdManager dd,
int  index 
)

Function********************************************************************

Synopsis [Checks whether a variable is set to be grouped.]

Description [Checks whether a variable is set to be grouped. This function is used for lazy sifting.]

SideEffects [none]

SeeAlso []

Definition at line 2067 of file cuddInt.c.

2070 {
2071  if (index >= dd->size || index < 0) return(-1);
2072  if (dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP)
2073  return(0);
2074  else
2075  return(dd->subtables[dd->perm[index]].varToBeGrouped);
2076 
2077 } /* end of Cudd_bddIsVarToBeGrouped */
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
Cudd_LazyGroupType varToBeGrouped
Definition: cuddInt.h:323
int * perm
Definition: cuddInt.h:369

◆ Cudd_bddIsVarToBeUngrouped()

int Cudd_bddIsVarToBeUngrouped ( DdManager dd,
int  index 
)

Function********************************************************************

Synopsis [Checks whether a variable is set to be ungrouped.]

Description [Checks whether a variable is set to be ungrouped. This function is used for lazy sifting. Returns 1 if the variable is marked to be ungrouped; 0 if the variable exists, but it is not marked to be ungrouped; -1 if the variable does not exist.]

SideEffects [none]

SeeAlso [Cudd_bddSetVarToBeUngrouped]

Definition at line 2096 of file cuddInt.c.

2099 {
2100  if (index >= dd->size || index < 0) return(-1);
2101  return dd->subtables[dd->perm[index]].varToBeGrouped == CUDD_LAZY_UNGROUP;
2102 
2103 } /* end of Cudd_bddIsVarToBeGrouped */
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
Cudd_LazyGroupType varToBeGrouped
Definition: cuddInt.h:323
int * perm
Definition: cuddInt.h:369

◆ Cudd_bddIte()

DdNode* Cudd_bddIte ( DdManager dd,
DdNode f,
DdNode g,
DdNode h 
)

AutomaticEnd Function********************************************************************

Synopsis [Implements ITE(f,g,h).]

Description [Implements ITE(f,g,h). Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_addIte Cudd_bddIteConstant Cudd_bddIntersect]

Definition at line 2942 of file cuddInt.c.

2947 {
2948  DdNode *res;
2949 
2950  do {
2951  dd->reordered = 0;
2952  res = cuddBddIteRecur(dd,f,g,h);
2953  } while (dd->reordered == 1);
2954  return(res);
2955 
2956 } /* end of Cudd_bddIte */
Definition: cudd.h:264
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:3380

◆ Cudd_bddIteConstant()

DdNode* Cudd_bddIteConstant ( DdManager dd,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Implements ITEconstant(f,g,h).]

Description [Implements ITEconstant(f,g,h). Returns a pointer to the resulting BDD (which may or may not be constant) or DD_NON_CONSTANT. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_bddIntersect Cudd_bddLeq Cudd_addIteConstant]

Definition at line 2974 of file cuddInt.c.

2979 {
2980  DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
2981  DdNode *one = DD_ONE(dd);
2982  DdNode *zero = Cudd_Not(one);
2983  int comple;
2984  unsigned int topf, topg, toph, v;
2985 
2986  statLine(dd);
2987  /* Trivial cases. */
2988  if (f == one) /* ITE(1,G,H) => G */
2989  return(g);
2990 
2991  if (f == zero) /* ITE(0,G,H) => H */
2992  return(h);
2993 
2994  /* f now not a constant. */
2995  bddVarToConst(f, &g, &h, one); /* possibly convert g or h */
2996  /* to constants */
2997 
2998  if (g == h) /* ITE(F,G,G) => G */
2999  return(g);
3000 
3001  if (Cudd_IsConstant(g) && Cudd_IsConstant(h))
3002  return(DD_NON_CONSTANT); /* ITE(F,1,0) or ITE(F,0,1) */
3003  /* => DD_NON_CONSTANT */
3004 
3005  if (g == Cudd_Not(h))
3006  return(DD_NON_CONSTANT); /* ITE(F,G,G') => DD_NON_CONSTANT */
3007  /* if F != G and F != G' */
3008 
3009  comple = bddVarToCanonical(dd, &f, &g, &h, &topf, &topg, &toph);
3010 
3011  /* Cache lookup. */
3012  r = cuddConstantLookup(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h);
3013  if (r != NULL) {
3014  return(Cudd_NotCond(r,comple && r != DD_NON_CONSTANT));
3015  }
3016 
3017  v = ddMin(topg, toph);
3018 
3019  /* ITE(F,G,H) = (v,G,H) (non constant) if F = (v,1,0), v < top(G,H). */
3020  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
3021  return(DD_NON_CONSTANT);
3022  }
3023 
3024  /* Compute cofactors. */
3025  if (topf <= v) {
3026  v = ddMin(topf, v); /* v = top_var(F,G,H) */
3027  Fv = cuddT(f); Fnv = cuddE(f);
3028  } else {
3029  Fv = Fnv = f;
3030  }
3031 
3032  if (topg == v) {
3033  Gv = cuddT(g); Gnv = cuddE(g);
3034  } else {
3035  Gv = Gnv = g;
3036  }
3037 
3038  if (toph == v) {
3039  H = Cudd_Regular(h);
3040  Hv = cuddT(H); Hnv = cuddE(H);
3041  if (Cudd_IsComplement(h)) {
3042  Hv = Cudd_Not(Hv);
3043  Hnv = Cudd_Not(Hnv);
3044  }
3045  } else {
3046  Hv = Hnv = h;
3047  }
3048 
3049  /* Recursion. */
3050  t = Cudd_bddIteConstant(dd, Fv, Gv, Hv);
3051  if (t == DD_NON_CONSTANT || !Cudd_IsConstant(t)) {
3053  return(DD_NON_CONSTANT);
3054  }
3055  e = Cudd_bddIteConstant(dd, Fnv, Gnv, Hnv);
3056  if (e == DD_NON_CONSTANT || !Cudd_IsConstant(e) || t != e) {
3058  return(DD_NON_CONSTANT);
3059  }
3060  cuddCacheInsert(dd, DD_BDD_ITE_CONSTANT_TAG, f, g, h, t);
3061  return(Cudd_NotCond(t,comple));
3062 
3063 } /* end of Cudd_bddIteConstant */
DdNode * cuddConstantLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:4756
static void bddVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *one)
Definition: cuddInt.c:3882
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define DD_BDD_ITE_CONSTANT_TAG
Definition: cuddInt.h:187
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_IsConstant(node)
Definition: cudd.h:328
#define Cudd_Regular(node)
Definition: cudd.h:373
static int bddVarToCanonical(DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
Definition: cuddInt.c:3917
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddInt.c:4283
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:359
static DdNode * zero
Definition: cuddInt.c:16562
DdNode * Cudd_bddIteConstant(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:2974
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_NON_CONSTANT
Definition: cuddInt.h:124

◆ Cudd_bddIthVar()

DdNode* Cudd_bddIthVar ( DdManager dd,
int  i 
)

AutomaticEnd Function********************************************************************

Synopsis [Returns the BDD variable with index i.]

Description [Retrieves the BDD variable with index i if it already exists, or creates a new BDD variable. Returns a pointer to the variable if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddNewVar Cudd_addIthVar Cudd_bddNewVarAtLevel Cudd_ReadVars]

Definition at line 1685 of file cuddInt.c.

1688 {
1689  DdNode *res;
1690 
1691  if ((unsigned int) i >= CUDD_MAXINDEX - 1) return(NULL);
1692  if (i < dd->size) {
1693  res = dd->vars[i];
1694  } else {
1695  res = cuddUniqueInter(dd,i,dd->one,Cudd_Not(dd->one));
1696  }
1697 
1698  return(res);
1699 
1700 } /* end of Cudd_bddIthVar */
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
DdNode ** vars
Definition: cuddInt.h:373
DdNode * one
Definition: cuddInt.h:329
#define CUDD_MAXINDEX
Definition: cudd.h:102

◆ Cudd_bddLeq()

int Cudd_bddLeq ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Determines whether f is less than or equal to g.]

Description [Returns 1 if f is less than or equal to g; 0 otherwise. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_bddIteConstant Cudd_addEvalConst]

Definition at line 3283 of file cuddInt.c.

3287 {
3288  DdNode *one, *zero, *tmp, *F, *fv, *fvn, *gv, *gvn;
3289  unsigned int topf, topg, res;
3290 
3291  statLine(dd);
3292  /* Terminal cases and normalization. */
3293  if (f == g) return(1);
3294 
3295  if (Cudd_IsComplement(g)) {
3296  /* Special case: if f is regular and g is complemented,
3297  ** f(1,...,1) = 1 > 0 = g(1,...,1).
3298  */
3299  if (!Cudd_IsComplement(f)) return(0);
3300  /* Both are complemented: Swap and complement because
3301  ** f <= g <=> g' <= f' and we want the second argument to be regular.
3302  */
3303  tmp = g;
3304  g = Cudd_Not(f);
3305  f = Cudd_Not(tmp);
3306  } else if (Cudd_IsComplement(f) && g < f) {
3307  tmp = g;
3308  g = Cudd_Not(f);
3309  f = Cudd_Not(tmp);
3310  }
3311 
3312  /* Now g is regular and, if f is not regular, f < g. */
3313  one = DD_ONE(dd);
3314  if (g == one) return(1); /* no need to test against zero */
3315  if (f == one) return(0); /* since at this point g != one */
3316  if (Cudd_Not(f) == g) return(0); /* because neither is constant */
3317  zero = Cudd_Not(one);
3318  if (f == zero) return(1);
3319 
3320  /* Here neither f nor g is constant. */
3321 
3322  /* Check cache. */
3323  tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g);
3324  if (tmp != NULL) {
3325  return(tmp == one);
3326  }
3327 
3328  /* Compute cofactors. */
3329  F = Cudd_Regular(f);
3330  topf = dd->perm[F->index];
3331  topg = dd->perm[g->index];
3332  if (topf <= topg) {
3333  fv = cuddT(F); fvn = cuddE(F);
3334  if (f != F) {
3335  fv = Cudd_Not(fv);
3336  fvn = Cudd_Not(fvn);
3337  }
3338  } else {
3339  fv = fvn = f;
3340  }
3341  if (topg <= topf) {
3342  gv = cuddT(g); gvn = cuddE(g);
3343  } else {
3344  gv = gvn = g;
3345  }
3346 
3347  /* Recursive calls. Since we want to maximize the probability of
3348  ** the special case f(1,...,1) > g(1,...,1), we consider the negative
3349  ** cofactors first. Indeed, the complementation parity of the positive
3350  ** cofactors is the same as the one of the parent functions.
3351  */
3352  res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv);
3353 
3354  /* Store result in cache and return. */
3355  cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero));
3356  return(res);
3357 
3358 } /* end of Cudd_bddLeq */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:297
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
#define cuddT(node)
Definition: cuddInt.h:609
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3283
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329

◆ Cudd_bddLeqUnless()

int Cudd_bddLeqUnless ( DdManager dd,
DdNode f,
DdNode g,
DdNode D 
)

Function********************************************************************

Synopsis [Tells whether f is less than of equal to G unless D is 1.]

Description [Tells whether f is less than of equal to G unless D is

  1. f, g, and D are BDDs. The function returns 1 if f is less than of equal to G, and 0 otherwise. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_EquivDC Cudd_bddLeq Cudd_bddIteConstant]

Definition at line 16870 of file cuddInt.c.

16875  {
16876  DdNode *tmp, *One, *F, *G;
16877  DdNode *Ft, *Fe, *Gt, *Ge, *Dt, *De;
16878  int res;
16879  unsigned int flevel, glevel, dlevel, top;
16880 
16881  statLine(dd);
16882 
16883  One = DD_ONE(dd);
16884 
16885  /* Check terminal cases. */
16886  if (f == g || g == One || f == Cudd_Not(One) || D == One ||
16887  D == f || D == Cudd_Not(g)) return(1);
16888  /* Check for two-operand cases. */
16889  if (D == Cudd_Not(One) || D == g || D == Cudd_Not(f))
16890  return(Cudd_bddLeq(dd,f,g));
16891  if (g == Cudd_Not(One) || g == Cudd_Not(f)) return(Cudd_bddLeq(dd,f,D));
16892  if (f == One) return(Cudd_bddLeq(dd,Cudd_Not(g),D));
16893 
16894  /* From now on, f, g, and D are non-constant, distinct, and
16895  ** non-complementary. */
16896 
16897  /* Normalize call to increase cache efficiency. We rely on the
16898  ** fact that f <= g unless D is equivalent to not(g) <= not(f)
16899  ** unless D and to f <= D unless g. We make sure that D is
16900  ** regular, and that at most one of f and g is complemented. We also
16901  ** ensure that when two operands can be swapped, the one with the
16902  ** lowest address comes first. */
16903 
16904  if (Cudd_IsComplement(D)) {
16905  if (Cudd_IsComplement(g)) {
16906  /* Special case: if f is regular and g is complemented,
16907  ** f(1,...,1) = 1 > 0 = g(1,...,1). If D(1,...,1) = 0, return 0.
16908  */
16909  if (!Cudd_IsComplement(f)) return(0);
16910  /* !g <= D unless !f or !D <= g unless !f */
16911  tmp = D;
16912  D = Cudd_Not(f);
16913  if (g < tmp) {
16914  f = Cudd_Not(g);
16915  g = tmp;
16916  } else {
16917  f = Cudd_Not(tmp);
16918  }
16919  } else {
16920  if (Cudd_IsComplement(f)) {
16921  /* !D <= !f unless g or !D <= g unless !f */
16922  tmp = f;
16923  f = Cudd_Not(D);
16924  if (tmp < g) {
16925  D = g;
16926  g = Cudd_Not(tmp);
16927  } else {
16928  D = Cudd_Not(tmp);
16929  }
16930  } else {
16931  /* f <= D unless g or !D <= !f unless g */
16932  tmp = D;
16933  D = g;
16934  if (tmp < f) {
16935  g = Cudd_Not(f);
16936  f = Cudd_Not(tmp);
16937  } else {
16938  g = tmp;
16939  }
16940  }
16941  }
16942  } else {
16943  if (Cudd_IsComplement(g)) {
16944  if (Cudd_IsComplement(f)) {
16945  /* !g <= !f unless D or !g <= D unless !f */
16946  tmp = f;
16947  f = Cudd_Not(g);
16948  if (D < tmp) {
16949  g = D;
16950  D = Cudd_Not(tmp);
16951  } else {
16952  g = Cudd_Not(tmp);
16953  }
16954  } else {
16955  /* f <= g unless D or !g <= !f unless D */
16956  if (g < f) {
16957  tmp = g;
16958  g = Cudd_Not(f);
16959  f = Cudd_Not(tmp);
16960  }
16961  }
16962  } else {
16963  /* f <= g unless D or f <= D unless g */
16964  if (D < g) {
16965  tmp = D;
16966  D = g;
16967  g = tmp;
16968  }
16969  }
16970  }
16971 
16972  /* From now on, D is regular. */
16973 
16974  /* Check cache. */
16975  tmp = cuddCacheLookup(dd,DD_BDD_LEQ_UNLESS_TAG,f,g,D);
16976  if (tmp != NULL) return(tmp == One);
16977 
16978  /* Find splitting variable. */
16979  F = Cudd_Regular(f);
16980  flevel = dd->perm[F->index];
16981  G = Cudd_Regular(g);
16982  glevel = dd->perm[G->index];
16983  top = ddMin(flevel,glevel);
16984  dlevel = dd->perm[D->index];
16985  top = ddMin(top,dlevel);
16986 
16987  /* Compute cofactors. */
16988  if (top == flevel) {
16989  Ft = cuddT(F);
16990  Fe = cuddE(F);
16991  if (F != f) {
16992  Ft = Cudd_Not(Ft);
16993  Fe = Cudd_Not(Fe);
16994  }
16995  } else {
16996  Ft = Fe = f;
16997  }
16998  if (top == glevel) {
16999  Gt = cuddT(G);
17000  Ge = cuddE(G);
17001  if (G != g) {
17002  Gt = Cudd_Not(Gt);
17003  Ge = Cudd_Not(Ge);
17004  }
17005  } else {
17006  Gt = Ge = g;
17007  }
17008  if (top == dlevel) {
17009  Dt = cuddT(D);
17010  De = cuddE(D);
17011  } else {
17012  Dt = De = D;
17013  }
17014 
17015  /* Solve recursively. */
17016  res = Cudd_bddLeqUnless(dd,Ft,Gt,Dt);
17017  if (res != 0) {
17018  res = Cudd_bddLeqUnless(dd,Fe,Ge,De);
17019  }
17021 
17022  return(res);
17023 
17024  } /* end of Cudd_bddLeqUnless */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:4413
#define Cudd_Regular(node)
Definition: cudd.h:373
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#define DD_BDD_LEQ_UNLESS_TAG
Definition: cuddInt.h:189
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3283
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddInt.c:4283
int Cudd_bddLeqUnless(DdManager *dd, DdNode *f, DdNode *g, DdNode *D)
Definition: cuddInt.c:16870
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:359
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369

◆ Cudd_bddMakePrime()

DdNode* Cudd_bddMakePrime ( DdManager dd,
DdNode cube,
DdNode f 
)

Function********************************************************************

Synopsis [Expands cube to a prime implicant of f.]

Description [Expands cube to a prime implicant of f. Returns the prime if successful; NULL otherwise. In particular, NULL is returned if cube is not a real cube or is not an implicant of f.]

SideEffects [None]

SeeAlso [Cudd_bddMaximallyExpand]

Definition at line 17112 of file cuddInt.c.

17116  {
17117  DdNode *res;
17118 
17119  if (!Cudd_bddLeq(dd,cube,f)) return(NULL);
17120 
17121  do {
17122  dd->reordered = 0;
17123  res = cuddBddMakePrime(dd,cube,f);
17124  } while (dd->reordered == 1);
17125  return(res);
17126 
17127  } /* end of Cudd_bddMakePrime */
Definition: cudd.h:264
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddMakePrime(DdManager *dd, DdNode *cube, DdNode *f)
Definition: cuddInt.c:17148
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3283

◆ Cudd_bddOr()

DdNode* Cudd_bddOr ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Computes the disjunction of two BDDs f and g.]

Description [Computes the disjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddNand Cudd_bddNor Cudd_bddXor Cudd_bddXnor]

Definition at line 3181 of file cuddInt.c.

3185 {
3186  DdNode *res;
3187 
3188  do {
3189  dd->reordered = 0;
3190  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
3191  } while (dd->reordered == 1);
3192  res = Cudd_NotCond(res,res != NULL);
3193  return(res);
3194 
3195 } /* end of Cudd_bddOr */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
int reordered
Definition: cuddInt.h:392
#define Cudd_NotCond(node, c)
Definition: cudd.h:359
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633

◆ Cudd_bddOrLimit()

DdNode* Cudd_bddOrLimit ( DdManager dd,
DdNode f,
DdNode g,
unsigned int  limit 
)

Function********************************************************************

Synopsis [Computes the disjunction of two BDDs f and g. Returns NULL if too many nodes are required.]

Description [Computes the disjunction of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up or more new nodes than limit are required.]

SideEffects [None]

SeeAlso [Cudd_bddOr]

Definition at line 3214 of file cuddInt.c.

3219 {
3220  DdNode *res;
3221  unsigned int saveLimit = dd->maxLive;
3222 
3223  dd->maxLive = (dd->keys - dd->dead) + (dd->keysZ - dd->deadZ) + limit;
3224  do {
3225  dd->reordered = 0;
3226  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(g));
3227  } while (dd->reordered == 1);
3228  dd->maxLive = saveLimit;
3229  res = Cudd_NotCond(res,res != NULL);
3230  return(res);
3231 
3232 } /* end of Cudd_bddOrLimit */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
unsigned int deadZ
Definition: cuddInt.h:356
int reordered
Definition: cuddInt.h:392
unsigned int dead
Definition: cuddInt.h:355
unsigned int maxLive
Definition: cuddInt.h:357
unsigned int keys
Definition: cuddInt.h:353
#define Cudd_NotCond(node, c)
Definition: cudd.h:359
unsigned int keysZ
Definition: cuddInt.h:354
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633

◆ Cudd_bddReadPairIndex()

int Cudd_bddReadPairIndex ( DdManager dd,
int  index 
)

Function********************************************************************

Synopsis [Reads a corresponding pair index for a given index.]

Description [Reads a corresponding pair index for a given index. These pair indices are present and next state variable. Returns the corresponding variable index if the variable exists; -1 otherwise.]

SideEffects [modifies the manager]

SeeAlso [Cudd_bddSetPairIndex]

Definition at line 2044 of file cuddInt.c.

2047 {
2048  if (index >= dd->size || index < 0) return -1;
2049  return dd->subtables[dd->perm[index]].pairIndex;
2050 
2051 } /* end of Cudd_bddReadPairIndex */
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
int pairIndex
Definition: cuddInt.h:321
int * perm
Definition: cuddInt.h:369

◆ Cudd_BddToCubeArray()

int Cudd_BddToCubeArray ( DdManager dd,
DdNode cube,
int *  array 
)

Function********************************************************************

Synopsis [Builds a positional array from the BDD of a cube.]

Description [Builds a positional array from the BDD of a cube. Array must have one entry for each BDD variable. The positional array has 1 in i-th position if the variable of index i appears in true form in the cube; it has 0 in i-th position if the variable of index i appears in complemented form in the cube; finally, it has 2 in i-th position if the variable of index i does not appear in the cube. Returns 1 if successful (the BDD is indeed a cube); 0 otherwise.]

SideEffects [The result is in the array passed by reference.]

SeeAlso [Cudd_CubeArrayToBdd]

Definition at line 22669 of file cuddInt.c.

22673 {
22674 DdNode *scan, *t, *e;
22675 int i;
22676 int size = Cudd_ReadSize(dd);
22677 DdNode *zero = Cudd_Not(DD_ONE(dd));
22678 
22679 for (i = size-1; i >= 0; i--) {
22680 array[i] = 2;
22681 }
22682 scan = cube;
22683 while (!Cudd_IsConstant(scan)) {
22684 int index = Cudd_Regular(scan)->index;
22685 cuddGetBranches(scan,&t,&e);
22686 if (t == zero) {
22687 array[index] = 0;
22688 scan = e;
22689 } else if (e == zero) {
22690 array[index] = 1;
22691 scan = t;
22692 } else {
22693 return(0); /* cube is not a cube */
22694 }
22695 }
22696 if (scan == zero) {
22697 return(0);
22698 } else {
22699 return(1);
22700 }
22701 
22702 } /* end of Cudd_BddToCubeArray */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_IsConstant(node)
Definition: cudd.h:328
#define Cudd_Regular(node)
Definition: cudd.h:373
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
Definition: cuddInt.c:6196
int Cudd_ReadSize(DdManager *dd)
Definition: cuddInt.c:1787
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ Cudd_bddVarIsDependent()

int Cudd_bddVarIsDependent ( DdManager dd,
DdNode f,
DdNode var 
)

Function********************************************************************

Synopsis [Checks whether a variable is dependent on others in a function.]

Description [Checks whether a variable is dependent on others in a function. Returns 1 if the variable is dependent; 0 otherwise. No new nodes are created.]

SideEffects [None]

SeeAlso []

Definition at line 2369 of file cuddInt.c.

2373 {
2374  DdNode *F, *res, *zero, *ft, *fe;
2375  unsigned topf, level;
2376  DD_CTFP cacheOp;
2377  int retval;
2378 
2379  zero = Cudd_Not(DD_ONE(dd));
2380  if (Cudd_IsConstant(f)) return(f == zero);
2381 
2382  /* From now on f is not constant. */
2383  F = Cudd_Regular(f);
2384  topf = (unsigned) dd->perm[F->index];
2385  level = (unsigned) dd->perm[var->index];
2386 
2387  /* Check terminal case. If topf > index of var, f does not depend on var.
2388  ** Therefore, var is not dependent in f. */
2389  if (topf > level) {
2390  return(0);
2391  }
2392 
2393  cacheOp = (DD_CTFP) Cudd_bddVarIsDependent;
2394  res = cuddCacheLookup2(dd,cacheOp,f,var);
2395  if (res != NULL) {
2396  return(res != zero);
2397  }
2398 
2399  /* Compute cofactors. */
2400  ft = Cudd_NotCond(cuddT(F), f != F);
2401  fe = Cudd_NotCond(cuddE(F), f != F);
2402 
2403  if (topf == level) {
2404  retval = Cudd_bddLeq(dd,ft,Cudd_Not(fe));
2405  } else {
2406  retval = Cudd_bddVarIsDependent(dd,ft,var) &&
2407  Cudd_bddVarIsDependent(dd,fe,var);
2408  }
2409 
2410  cuddCacheInsert2(dd,cacheOp,f,var,Cudd_NotCond(zero,retval));
2411 
2412  return(retval);
2413 
2414 } /* Cudd_bddVarIsDependent */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_IsConstant(node)
Definition: cudd.h:328
#define Cudd_Regular(node)
Definition: cudd.h:373
int Cudd_bddVarIsDependent(DdManager *dd, DdNode *f, DdNode *var)
Definition: cuddInt.c:2369
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:297
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
#define cuddT(node)
Definition: cuddInt.h:609
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3283
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:359
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329

◆ Cudd_bddXor()

DdNode* Cudd_bddXor ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Computes the exclusive OR of two BDDs f and g.]

Description [Computes the exclusive OR of two BDDs f and g. Returns a pointer to the resulting BDD if successful; NULL if the intermediate result blows up.]

SideEffects [None]

SeeAlso [Cudd_bddIte Cudd_addApply Cudd_bddAnd Cudd_bddOr Cudd_bddNand Cudd_bddNor Cudd_bddXnor]

Definition at line 3253 of file cuddInt.c.

3257 {
3258  DdNode *res;
3259 
3260  do {
3261  dd->reordered = 0;
3262  res = cuddBddXorRecur(dd,f,g);
3263  } while (dd->reordered == 1);
3264  return(res);
3265 
3266 } /* end of Cudd_bddXor */
Definition: cudd.h:264
int reordered
Definition: cuddInt.h:392
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3761

◆ Cudd_CheckCube()

int Cudd_CheckCube ( DdManager dd,
DdNode g 
)

Function********************************************************************

Synopsis [Checks whether g is the BDD of a cube.]

Description [Checks whether g is the BDD of a cube. Returns 1 in case of success; 0 otherwise. The constant 1 is a valid cube, but all other constant functions cause cuddCheckCube to return 0.]

SideEffects [None]

SeeAlso []

Definition at line 6155 of file cuddInt.c.

6158 {
6159  DdNode *g1,*g0,*one,*zero;
6160 
6161  one = DD_ONE(dd);
6162  if (g == one) return(1);
6163  if (Cudd_IsConstant(g)) return(0);
6164 
6165  zero = Cudd_Not(one);
6166  cuddGetBranches(g,&g1,&g0);
6167 
6168  if (g0 == zero) {
6169  return(Cudd_CheckCube(dd, g1));
6170  }
6171  if (g1 == zero) {
6172  return(Cudd_CheckCube(dd, g0));
6173  }
6174  return(0);
6175 
6176 } /* end of Cudd_CheckCube */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_IsConstant(node)
Definition: cudd.h:328
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
Definition: cuddInt.c:6196
int Cudd_CheckCube(DdManager *dd, DdNode *g)
Definition: cuddInt.c:6155
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ Cudd_CheckKeys()

int Cudd_CheckKeys ( DdManager table)

Function********************************************************************

Synopsis [Checks for several conditions that should not occur.]

Description [Checks for the following conditions:

  • Wrong sizes of subtables.
  • Wrong number of keys found in unique subtable.
  • Wrong number of dead found in unique subtable.
  • Wrong number of keys found in the constant table
  • Wrong number of dead found in the constant table
  • Wrong number of total slots found
  • Wrong number of maximum keys found
  • Wrong number of total dead found

Reports the average length of non-empty lists. Returns the number of subtables for which the number of keys is wrong.]

SideEffects [None]

SeeAlso [Cudd_DebugCheck]

Definition at line 5577 of file cuddInt.c.

5579 {
5580  int size;
5581  int i,j;
5582  DdNodePtr *nodelist;
5583  DdNode *node;
5584  DdNode *sentinel = &(table->sentinel);
5585  DdSubtable *subtable;
5586  int keys;
5587  int dead;
5588  int count = 0;
5589  int totalKeys = 0;
5590  int totalSlots = 0;
5591  int totalDead = 0;
5592  int nonEmpty = 0;
5593  unsigned int slots;
5594  int logSlots;
5595  int shift;
5596 
5597  size = table->size;
5598 
5599  for (i = 0; i < size; i++) {
5600  subtable = &(table->subtables[i]);
5601  nodelist = subtable->nodelist;
5602  keys = subtable->keys;
5603  dead = subtable->dead;
5604  totalKeys += keys;
5605  slots = subtable->slots;
5606  shift = subtable->shift;
5607  logSlots = sizeof(int) * 8 - shift;
5608  if (((slots >> logSlots) << logSlots) != slots) {
5609  (void) fprintf(table->err,
5610  "Unique table %d is not the right power of 2\n", i);
5611  (void) fprintf(table->err,
5612  " slots = %u shift = %d\n", slots, shift);
5613  }
5614  totalSlots += slots;
5615  totalDead += dead;
5616  for (j = 0; (unsigned) j < slots; j++) {
5617  node = nodelist[j];
5618  if (node != sentinel) {
5619  nonEmpty++;
5620  }
5621  while (node != sentinel) {
5622  keys--;
5623  if (node->ref == 0) {
5624  dead--;
5625  }
5626  node = node->next;
5627  }
5628  }
5629  if (keys != 0) {
5630  (void) fprintf(table->err, "Wrong number of keys found \
5631 in unique table %d (difference=%d)\n", i, keys);
5632  count++;
5633  }
5634  if (dead != 0) {
5635  (void) fprintf(table->err, "Wrong number of dead found \
5636 in unique table no. %d (difference=%d)\n", i, dead);
5637  }
5638  } /* for each BDD/ADD subtable */
5639 
5640  /* Check the ZDD subtables. */
5641  size = table->sizeZ;
5642 
5643  for (i = 0; i < size; i++) {
5644  subtable = &(table->subtableZ[i]);
5645  nodelist = subtable->nodelist;
5646  keys = subtable->keys;
5647  dead = subtable->dead;
5648  totalKeys += keys;
5649  totalSlots += subtable->slots;
5650  totalDead += dead;
5651  for (j = 0; (unsigned) j < subtable->slots; j++) {
5652  node = nodelist[j];
5653  if (node != NULL) {
5654  nonEmpty++;
5655  }
5656  while (node != NULL) {
5657  keys--;
5658  if (node->ref == 0) {
5659  dead--;
5660  }
5661  node = node->next;
5662  }
5663  }
5664  if (keys != 0) {
5665  (void) fprintf(table->err, "Wrong number of keys found \
5666 in ZDD unique table no. %d (difference=%d)\n", i, keys);
5667  count++;
5668  }
5669  if (dead != 0) {
5670  (void) fprintf(table->err, "Wrong number of dead found \
5671 in ZDD unique table no. %d (difference=%d)\n", i, dead);
5672  }
5673  } /* for each ZDD subtable */
5674 
5675  /* Check the constant table. */
5676  subtable = &(table->constants);
5677  nodelist = subtable->nodelist;
5678  keys = subtable->keys;
5679  dead = subtable->dead;
5680  totalKeys += keys;
5681  totalSlots += subtable->slots;
5682  totalDead += dead;
5683  for (j = 0; (unsigned) j < subtable->slots; j++) {
5684  node = nodelist[j];
5685  if (node != NULL) {
5686  nonEmpty++;
5687  }
5688  while (node != NULL) {
5689  keys--;
5690  if (node->ref == 0) {
5691  dead--;
5692  }
5693  node = node->next;
5694  }
5695  }
5696  if (keys != 0) {
5697  (void) fprintf(table->err, "Wrong number of keys found \
5698 in the constant table (difference=%d)\n", keys);
5699  count++;
5700  }
5701  if (dead != 0) {
5702  (void) fprintf(table->err, "Wrong number of dead found \
5703 in the constant table (difference=%d)\n", dead);
5704  }
5705  if ((unsigned) totalKeys != table->keys + table->keysZ) {
5706  (void) fprintf(table->err, "Wrong number of total keys found \
5707 (difference=%d)\n", (int) (totalKeys-table->keys));
5708  }
5709  if ((unsigned) totalSlots != table->slots) {
5710  (void) fprintf(table->err, "Wrong number of total slots found \
5711 (difference=%d)\n", (int) (totalSlots-table->slots));
5712  }
5713  if (table->minDead != (unsigned) (table->gcFrac * table->slots)) {
5714  (void) fprintf(table->err, "Wrong number of minimum dead found \
5715 (%u vs. %u)\n", table->minDead,
5716  (unsigned) (table->gcFrac * (double) table->slots));
5717  }
5718  if ((unsigned) totalDead != table->dead + table->deadZ) {
5719  (void) fprintf(table->err, "Wrong number of total dead found \
5720 (difference=%d)\n", (int) (totalDead-table->dead));
5721  }
5722  (void) fprintf(table->out,"Average length of non-empty lists = %g\n",
5723  (double) table->keys / (double) nonEmpty);
5724 
5725  return(count);
5726 
5727 } /* end of Cudd_CheckKeys */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
Definition: cudd.h:264
unsigned int deadZ
Definition: cuddInt.h:356
int size
Definition: cuddInt.h:345
double gcFrac
Definition: cuddInt.h:359
unsigned int slots
Definition: cuddInt.h:352
FILE * err
Definition: cuddInt.h:424
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int dead
Definition: cuddInt.h:355
DdNode sentinel
Definition: cuddInt.h:328
unsigned int keys
Definition: cuddInt.h:353
unsigned int dead
Definition: cuddInt.h:316
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:267
DdNode ** nodelist
Definition: cuddInt.h:311
int sizeZ
Definition: cuddInt.h:346
unsigned int slots
Definition: cuddInt.h:313
DdSubtable constants
Definition: cuddInt.h:351
int shift
Definition: cuddInt.h:312
unsigned int keysZ
Definition: cuddInt.h:354
unsigned int minDead
Definition: cuddInt.h:358
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ Cudd_Cofactor()

DdNode* Cudd_Cofactor ( DdManager dd,
DdNode f,
DdNode g 
)

CFile***********************************************************************

FileName [cuddCof.c]

PackageName [cudd]

Synopsis [Cofactoring functions.]

Description [External procedures included in this module:

Internal procedures included in this module:

]

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Computes the cofactor of f with respect to g.]

Description [Computes the cofactor of f with respect to g; g must be the BDD or the ADD of a cube. Returns a pointer to the cofactor if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddConstrain Cudd_bddRestrict]

Definition at line 6119 of file cuddInt.c.

6123 {
6124  DdNode *res,*zero;
6125 
6126  zero = Cudd_Not(DD_ONE(dd));
6127  if (g == zero || g == DD_ZERO(dd)) {
6128  (void) fprintf(dd->err,"Cudd_Cofactor: Invalid restriction 1\n");
6130  return(NULL);
6131  }
6132  do {
6133  dd->reordered = 0;
6134  res = cuddCofactorRecur(dd,f,g);
6135  } while (dd->reordered == 1);
6136  return(res);
6137 
6138 } /* end of Cudd_Cofactor */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
FILE * err
Definition: cuddInt.h:424
DdNode * cuddCofactorRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:6226
int reordered
Definition: cuddInt.h:392
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ Cudd_CountMinterm()

double Cudd_CountMinterm ( DdManager manager,
DdNode node,
int  nvars 
)

AutomaticEnd Function********************************************************************

Synopsis [Counts the number of minterms of a DD.]

Description [Counts the number of minterms of a DD. The function is assumed to depend on nvars variables. The minterm count is represented as a double, to allow for a larger number of variables. Returns the number of minterms of the function rooted at node if successful; (double) CUDD_OUT_OF_MEM otherwise.]

SideEffects [None]

SeeAlso [Cudd_PrintDebug Cudd_CountPath]

Definition at line 22209 of file cuddInt.c.

22213 {
22214 double max;
22215 DdHashTable *table;
22216 double res;
22217 CUDD_VALUE_TYPE epsilon;
22218 
22219 background = manager->background;
22220 zero = Cudd_Not(manager->one);
22221 
22222 max = pow(2.0,(double)nvars);
22223 table = cuddHashTableInit(manager,1,2);
22224 if (table == NULL) {
22225 return((double)CUDD_OUT_OF_MEM);
22226 }
22227 epsilon = Cudd_ReadEpsilon(manager);
22228 Cudd_SetEpsilon(manager,(CUDD_VALUE_TYPE)0.0);
22229 res = ddCountMintermAux(node,max,table);
22230 cuddHashTableQuit(table);
22231 Cudd_SetEpsilon(manager,epsilon);
22232 
22233 return(res);
22234 
22235 } /* end of Cudd_CountMinterm */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
#define Cudd_Not(node)
Definition: cudd.h:343
static double ddCountMintermAux(DdNode *node, double max, DdHashTable *table)
Definition: cuddInt.c:23527
static DdNode * background
Definition: cuddInt.c:22141
CUDD_VALUE_TYPE Cudd_ReadEpsilon(DdManager *dd)
Definition: cuddInt.c:1883
void cuddHashTableQuit(DdHashTable *hash)
Definition: cuddInt.c:11598
void Cudd_SetEpsilon(DdManager *dd, CUDD_VALUE_TYPE ep)
Definition: cuddInt.c:1904
DdHashTable * cuddHashTableInit(DdManager *manager, unsigned int keySize, unsigned int initSize)
Definition: cuddInt.c:11548
#define CUDD_VALUE_TYPE
Definition: cudd.h:87
DdNode * one
Definition: cuddInt.h:329
static DdNode * zero
Definition: cuddInt.c:16562
DdNode * background
Definition: cuddInt.h:333

◆ Cudd_DebugCheck()

int Cudd_DebugCheck ( DdManager table)

AutomaticEnd Function********************************************************************

Synopsis [Checks for inconsistencies in the DD heap.]

Description [Checks for inconsistencies in the DD heap:

  • node has illegal index
  • live node has dead children
  • node has illegal Then or Else pointers
  • BDD/ADD node has identical children
  • ZDD node has zero then child
  • wrong number of total nodes
  • wrong number of dead nodes
  • ref count error at node

Returns 0 if no inconsistencies are found; DD_OUT_OF_MEM if there is not enough memory; 1 otherwise.]

SideEffects [None]

SeeAlso [Cudd_CheckKeys]

Definition at line 5255 of file cuddInt.c.

5257 {
5258  unsigned int i;
5259  int j,count;
5260  int slots;
5261  DdNodePtr *nodelist;
5262  DdNode *f;
5263  DdNode *sentinel = &(table->sentinel);
5264  st_table *edgeTable; /* stores internal ref count for each node */
5265  st_generator *gen;
5266  int flag = 0;
5267  int totalNode;
5268  int deadNode;
5269  int index;
5270  int shift;
5271 
5272  edgeTable = st_init_table(st_ptrcmp,st_ptrhash);
5273  if (edgeTable == NULL) return(CUDD_OUT_OF_MEM);
5274 
5275  /* Check the BDD/ADD subtables. */
5276  for (i = 0; i < (unsigned) table->size; i++) {
5277  index = table->invperm[i];
5278  if (i != (unsigned) table->perm[index]) {
5279  (void) fprintf(table->err,
5280  "Permutation corrupted: invperm[%u] = %d\t perm[%d] = %d\n",
5281  i, index, index, table->perm[index]);
5282  }
5283  nodelist = table->subtables[i].nodelist;
5284  slots = table->subtables[i].slots;
5285  shift = table->subtables[i].shift;
5286 
5287  totalNode = 0;
5288  deadNode = 0;
5289  for (j = 0; j < slots; j++) { /* for each subtable slot */
5290  f = nodelist[j];
5291  while (f != sentinel) {
5292  totalNode++;
5293  if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) {
5294  if ((int) f->index != index) {
5295  (void) fprintf(table->err,
5296  "Error: node has illegal index\n");
5297  cuddPrintNode(f,table->err);
5298  flag = 1;
5299  }
5300  if ((unsigned) cuddI(table,cuddT(f)->index) <= i ||
5301  (unsigned) cuddI(table,Cudd_Regular(cuddE(f))->index)
5302  <= i) {
5303  (void) fprintf(table->err,
5304  "Error: node has illegal children\n");
5305  cuddPrintNode(f,table->err);
5306  flag = 1;
5307  }
5308  if (Cudd_Regular(cuddT(f)) != cuddT(f)) {
5309  (void) fprintf(table->err,
5310  "Error: node has illegal form\n");
5311  cuddPrintNode(f,table->err);
5312  flag = 1;
5313  }
5314  if (cuddT(f) == cuddE(f)) {
5315  (void) fprintf(table->err,
5316  "Error: node has identical children\n");
5317  cuddPrintNode(f,table->err);
5318  flag = 1;
5319  }
5320  if (cuddT(f)->ref == 0 || Cudd_Regular(cuddE(f))->ref == 0) {
5321  (void) fprintf(table->err,
5322  "Error: live node has dead children\n");
5323  cuddPrintNode(f,table->err);
5324  flag =1;
5325  }
5326  if (ddHash(cuddT(f),cuddE(f),shift) != j) {
5327  (void) fprintf(table->err, "Error: misplaced node\n");
5328  cuddPrintNode(f,table->err);
5329  flag =1;
5330  }
5331  /* Increment the internal reference count for the
5332  ** then child of the current node.
5333  */
5334  if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) {
5335  count++;
5336  } else {
5337  count = 1;
5338  }
5339  if (st_insert(edgeTable,(char *)cuddT(f),
5340  (char *)(long)count) == ST_OUT_OF_MEM) {
5341  st_free_table(edgeTable);
5342  return(CUDD_OUT_OF_MEM);
5343  }
5344 
5345  /* Increment the internal reference count for the
5346  ** else child of the current node.
5347  */
5348  if (st_lookup_int(edgeTable,(char *)Cudd_Regular(cuddE(f)),
5349  &count)) {
5350  count++;
5351  } else {
5352  count = 1;
5353  }
5354  if (st_insert(edgeTable,(char *)Cudd_Regular(cuddE(f)),
5355  (char *)(long)count) == ST_OUT_OF_MEM) {
5356  st_free_table(edgeTable);
5357  return(CUDD_OUT_OF_MEM);
5358  }
5359  } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) {
5360  deadNode++;
5361 #if 0
5362  debugCheckParent(table,f);
5363 #endif
5364  } else {
5365  fprintf(table->err,
5366  "Error: node has illegal Then or Else pointers\n");
5367  cuddPrintNode(f,table->err);
5368  flag = 1;
5369  }
5370 
5371  f = f->next;
5372  } /* for each element of the collision list */
5373  } /* for each subtable slot */
5374 
5375  if ((unsigned) totalNode != table->subtables[i].keys) {
5376  fprintf(table->err,"Error: wrong number of total nodes\n");
5377  flag = 1;
5378  }
5379  if ((unsigned) deadNode != table->subtables[i].dead) {
5380  fprintf(table->err,"Error: wrong number of dead nodes\n");
5381  flag = 1;
5382  }
5383  } /* for each BDD/ADD subtable */
5384 
5385  /* Check the ZDD subtables. */
5386  for (i = 0; i < (unsigned) table->sizeZ; i++) {
5387  index = table->invpermZ[i];
5388  if (i != (unsigned) table->permZ[index]) {
5389  (void) fprintf(table->err,
5390  "Permutation corrupted: invpermZ[%u] = %d\t permZ[%d] = %d in ZDD\n",
5391  i, index, index, table->permZ[index]);
5392  }
5393  nodelist = table->subtableZ[i].nodelist;
5394  slots = table->subtableZ[i].slots;
5395 
5396  totalNode = 0;
5397  deadNode = 0;
5398  for (j = 0; j < slots; j++) { /* for each subtable slot */
5399  f = nodelist[j];
5400  while (f != NULL) {
5401  totalNode++;
5402  if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref != 0) {
5403  if ((int) f->index != index) {
5404  (void) fprintf(table->err,
5405  "Error: ZDD node has illegal index\n");
5406  cuddPrintNode(f,table->err);
5407  flag = 1;
5408  }
5409  if (Cudd_IsComplement(cuddT(f)) ||
5410  Cudd_IsComplement(cuddE(f))) {
5411  (void) fprintf(table->err,
5412  "Error: ZDD node has complemented children\n");
5413  cuddPrintNode(f,table->err);
5414  flag = 1;
5415  }
5416  if ((unsigned) cuddIZ(table,cuddT(f)->index) <= i ||
5417  (unsigned) cuddIZ(table,cuddE(f)->index) <= i) {
5418  (void) fprintf(table->err,
5419  "Error: ZDD node has illegal children\n");
5420  cuddPrintNode(f,table->err);
5421  cuddPrintNode(cuddT(f),table->err);
5422  cuddPrintNode(cuddE(f),table->err);
5423  flag = 1;
5424  }
5425  if (cuddT(f) == DD_ZERO(table)) {
5426  (void) fprintf(table->err,
5427  "Error: ZDD node has zero then child\n");
5428  cuddPrintNode(f,table->err);
5429  flag = 1;
5430  }
5431  if (cuddT(f)->ref == 0 || cuddE(f)->ref == 0) {
5432  (void) fprintf(table->err,
5433  "Error: ZDD live node has dead children\n");
5434  cuddPrintNode(f,table->err);
5435  flag =1;
5436  }
5437  /* Increment the internal reference count for the
5438  ** then child of the current node.
5439  */
5440  if (st_lookup_int(edgeTable,(char *)cuddT(f),&count)) {
5441  count++;
5442  } else {
5443  count = 1;
5444  }
5445  if (st_insert(edgeTable,(char *)cuddT(f),
5446  (char *)(long)count) == ST_OUT_OF_MEM) {
5447  st_free_table(edgeTable);
5448  return(CUDD_OUT_OF_MEM);
5449  }
5450 
5451  /* Increment the internal reference count for the
5452  ** else child of the current node.
5453  */
5454  if (st_lookup_int(edgeTable,(char *)cuddE(f),&count)) {
5455  count++;
5456  } else {
5457  count = 1;
5458  }
5459  if (st_insert(edgeTable,(char *)cuddE(f),
5460  (char *)(long)count) == ST_OUT_OF_MEM) {
5461  st_free_table(edgeTable);
5462  table->errorCode = CUDD_MEMORY_OUT;
5463  return(CUDD_OUT_OF_MEM);
5464  }
5465  } else if (cuddT(f) != NULL && cuddE(f) != NULL && f->ref == 0) {
5466  deadNode++;
5467 #if 0
5468  debugCheckParent(table,f);
5469 #endif
5470  } else {
5471  fprintf(table->err,
5472  "Error: ZDD node has illegal Then or Else pointers\n");
5473  cuddPrintNode(f,table->err);
5474  flag = 1;
5475  }
5476 
5477  f = f->next;
5478  } /* for each element of the collision list */
5479  } /* for each subtable slot */
5480 
5481  if ((unsigned) totalNode != table->subtableZ[i].keys) {
5482  fprintf(table->err,
5483  "Error: wrong number of total nodes in ZDD\n");
5484  flag = 1;
5485  }
5486  if ((unsigned) deadNode != table->subtableZ[i].dead) {
5487  fprintf(table->err,
5488  "Error: wrong number of dead nodes in ZDD\n");
5489  flag = 1;
5490  }
5491  } /* for each ZDD subtable */
5492 
5493  /* Check the constant table. */
5494  nodelist = table->constants.nodelist;
5495  slots = table->constants.slots;
5496 
5497  totalNode = 0;
5498  deadNode = 0;
5499  for (j = 0; j < slots; j++) {
5500  f = nodelist[j];
5501  while (f != NULL) {
5502  totalNode++;
5503  if (f->ref != 0) {
5504  if (f->index != CUDD_CONST_INDEX) {
5505  fprintf(table->err,"Error: node has illegal index\n");
5506 #if SIZEOF_VOID_P == 8
5507  fprintf(table->err,
5508  " node 0x%lx, id = %u, ref = %u, value = %g\n",
5509  (ptruint)f,f->index,f->ref,cuddV(f));
5510 #else
5511  fprintf(table->err,
5512  " node 0x%x, id = %hu, ref = %hu, value = %g\n",
5513  (ptruint)f,f->index,f->ref,cuddV(f));
5514 #endif
5515  flag = 1;
5516  }
5517  } else {
5518  deadNode++;
5519  }
5520  f = f->next;
5521  }
5522  }
5523  if ((unsigned) totalNode != table->constants.keys) {
5524  (void) fprintf(table->err,
5525  "Error: wrong number of total nodes in constants\n");
5526  flag = 1;
5527  }
5528  if ((unsigned) deadNode != table->constants.dead) {
5529  (void) fprintf(table->err,
5530  "Error: wrong number of dead nodes in constants\n");
5531  flag = 1;
5532  }
5533  gen = st_init_gen(edgeTable);
5534  while (st_gen(gen, &f, &count)) {
5535  if (count > (int)(f->ref) && f->ref != DD_MAXREF) {
5536 #if SIZEOF_VOID_P == 8
5537  fprintf(table->err,"ref count error at node 0x%lx, count = %d, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f));
5538 #else
5539  fprintf(table->err,"ref count error at node 0x%x, count = %d, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,count,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f));
5540 #endif
5541  debugFindParent(table,f);
5542  flag = 1;
5543  }
5544  }
5545  st_free_gen(gen);
5546  st_free_table(edgeTable);
5547 
5548  return (flag);
5549 
5550 } /* end of Cudd_DebugCheck */
DdHalfWord ref
Definition: cudd.h:266
#define DD_MAXREF
Definition: cuddInt.h:101
unsigned int keys
Definition: cuddInt.h:314
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
#define ddHash(f, g, s)
Definition: cuddInt.h:696
Definition: st.h:60
#define cuddIZ(dd, index)
Definition: cuddInt.h:677
int st_lookup_int(st_table *, void *, int *)
Definition: st.c:307
Definition: cudd.h:264
void st_free_gen(st_generator *)
Definition: st.c:730
int * invpermZ
Definition: cuddInt.h:372
int size
Definition: cuddInt.h:345
void st_free_table(st_table *)
Definition: st.c:237
#define Cudd_Regular(node)
Definition: cudd.h:373
int st_gen(st_generator *, void *, void *)
Definition: st.c:644
FILE * err
Definition: cuddInt.h:424
st_generator * st_init_gen(st_table *)
Definition: st.c:606
DdSubtable * subtables
Definition: cuddInt.h:349
int * permZ
Definition: cuddInt.h:370
static void debugFindParent(DdManager *table, DdNode *node)
Definition: cuddInt.c:5929
#define cuddV(node)
Definition: cuddInt.h:641
int st_insert(st_table *, void *, void *)
Definition: st.c:343
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode sentinel
Definition: cuddInt.h:328
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:267
#define CUDD_CONST_INDEX
Definition: cudd.h:107
DdNode ** nodelist
Definition: cuddInt.h:311
int st_ptrcmp(const char *, const char *)
Definition: st.c:585
#define cuddT(node)
Definition: cuddInt.h:609
st_table * st_init_table(ST_PFICPCP, ST_PFICPI)
Definition: st.c:148
#define ST_OUT_OF_MEM
Definition: st.h:41
void cuddPrintNode(DdNode *f, FILE *fp)
Definition: cuddInt.c:5829
#define cuddI(dd, index)
Definition: cuddInt.h:659
unsigned int ptruint
Definition: cuddInt.h:250
int sizeZ
Definition: cuddInt.h:346
DdHalfWord index
Definition: cudd.h:265
unsigned int slots
Definition: cuddInt.h:313
#define cuddE(node)
Definition: cuddInt.h:625
int st_ptrhash(char *, int)
Definition: st.c:547
int * invperm
Definition: cuddInt.h:371
DdSubtable constants
Definition: cuddInt.h:351
int shift
Definition: cuddInt.h:312
int * perm
Definition: cuddInt.h:369
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:350
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ Cudd_Decreasing()

DdNode* Cudd_Decreasing ( DdManager dd,
DdNode f,
int  i 
)

Function********************************************************************

Synopsis [Determines whether a BDD is negative unate in a variable.]

Description [Determines whether the function represented by BDD f is negative unate (monotonic decreasing) in variable i. Returns the constant one is f is unate and the (logical) constant zero if it is not. This function does not generate any new nodes.]

SideEffects [None]

SeeAlso [Cudd_Increasing]

Definition at line 16691 of file cuddInt.c.

16695  {
16696  unsigned int topf, level;
16697  DdNode *F, *fv, *fvn, *res;
16698  DD_CTFP cacheOp;
16699 
16700  statLine(dd);
16701 #ifdef DD_DEBUG
16702  assert(0 <= i && i < dd->size);
16703 #endif
16704 
16705  F = Cudd_Regular(f);
16706  topf = cuddI(dd,F->index);
16707 
16708  /* Check terminal case. If topf > i, f does not depend on var.
16709  ** Therefore, f is unate in i.
16710  */
16711  level = (unsigned) dd->perm[i];
16712  if (topf > level) {
16713  return(DD_ONE(dd));
16714  }
16715 
16716  /* From now on, f is not constant. */
16717 
16718  /* Check cache. */
16719  cacheOp = (DD_CTFP) Cudd_Decreasing;
16720  res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]);
16721  if (res != NULL) {
16722  return(res);
16723  }
16724 
16725  /* Compute cofactors. */
16726  fv = cuddT(F); fvn = cuddE(F);
16727  if (F != f) {
16728  fv = Cudd_Not(fv);
16729  fvn = Cudd_Not(fvn);
16730  }
16731 
16732  if (topf == (unsigned) level) {
16733  /* Special case: if fv is regular, fv(1,...,1) = 1;
16734  ** If in addition fvn is complemented, fvn(1,...,1) = 0.
16735  ** But then f(1,1,...,1) > f(0,1,...,1). Hence f is not
16736  ** monotonic decreasing in i.
16737  */
16738  if (!Cudd_IsComplement(fv) && Cudd_IsComplement(fvn)) {
16739  return(Cudd_Not(DD_ONE(dd)));
16740  }
16741  res = Cudd_bddLeq(dd,fv,fvn) ? DD_ONE(dd) : Cudd_Not(DD_ONE(dd));
16742  } else {
16743  res = Cudd_Decreasing(dd,fv,i);
16744  if (res == DD_ONE(dd)) {
16745  res = Cudd_Decreasing(dd,fvn,i);
16746  }
16747  }
16748 
16749  cuddCacheInsert2(dd,cacheOp,f,dd->vars[i],res);
16750  return(res);
16751 
16752  } /* end of Cudd_Decreasing */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
if(DEFINED IN_SOURCE_BUILD) set(LLVM_LINK_COMPONENTS BitWriter Core IPO IrReader InstCombine Instrumentation Target Linker Analysis ScalarOpts Support Svf Cudd) add_llvm_tool(cfl cfl.cpp) else() add_executable(cfl cfl.cpp) target_link_libraries(cfl Svf Cudd $
Definition: CMakeLists.txt:2
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:373
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:297
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
DdNode * Cudd_Decreasing(DdManager *dd, DdNode *f, int i)
Definition: cuddInt.c:16691
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3283
DdHalfWord index
Definition: cudd.h:265
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329

◆ Cudd_Deref()

void Cudd_Deref ( DdNode node)

Function********************************************************************

Synopsis [Decreases the reference count of node.]

Description [Decreases the reference count of node. It is primarily used in recursive procedures to decrease the ref count of a result node before returning it. This accomplishes the goal of removing the protection applied by a previous Cudd_Ref.]

SideEffects [None]

SeeAlso [Cudd_RecursiveDeref Cudd_RecursiveDerefZdd Cudd_Ref]

Definition at line 14198 of file cuddInt.c.

14200 {
14201  node = Cudd_Regular(node);
14202  cuddSatDec(node->ref);
14203 
14204 } /* end of Cudd_Deref */
DdHalfWord ref
Definition: cudd.h:266
#define Cudd_Regular(node)
Definition: cudd.h:373
#define cuddSatDec(x)
Definition: cuddInt.h:849

◆ Cudd_EqualSupNorm()

int Cudd_EqualSupNorm ( DdManager dd,
DdNode f,
DdNode g,
CUDD_VALUE_TYPE  tolerance,
int  pr 
)

Function********************************************************************

Synopsis [Compares two ADDs for equality within tolerance.]

Description [Compares two ADDs for equality within tolerance. Two ADDs are reported to be equal if the maximum difference between them (the sup norm of their difference) is less than or equal to the tolerance parameter. Returns 1 if the two ADDs are equal (within tolerance); 0 otherwise. If parameter pr is positive the first failure is reported to the standard output.]

SideEffects [None]

SeeAlso []

Definition at line 17044 of file cuddInt.c.

17050  {
17051  DdNode *fv, *fvn, *gv, *gvn, *r;
17052  unsigned int topf, topg;
17053 
17054  statLine(dd);
17055  /* Check terminal cases. */
17056  if (f == g) return(1);
17057  if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) {
17058  if (ddEqualVal(cuddV(f),cuddV(g),tolerance)) {
17059  return(1);
17060  } else {
17061  if (pr>0) {
17062  (void) fprintf(dd->out,"Offending nodes:\n");
17063  (void) fprintf(dd->out,
17064  "f: address = %p\t value = %40.30f\n",
17065  (void *) f, cuddV(f));
17066  (void) fprintf(dd->out,
17067  "g: address = %p\t value = %40.30f\n",
17068  (void *) g, cuddV(g));
17069  }
17070  return(0);
17071  }
17072  }
17073 
17074  /* We only insert the result in the cache if the comparison is
17075  ** successful. Therefore, if we hit we return 1. */
17077  if (r != NULL) {
17078  return(1);
17079  }
17080 
17081  /* Compute the cofactors and solve the recursive subproblems. */
17082  topf = cuddI(dd,f->index);
17083  topg = cuddI(dd,g->index);
17084 
17085  if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;}
17086  if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;}
17087 
17088  if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0);
17089  if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0);
17090 
17092 
17093  return(1);
17094 
17095  } /* end of Cudd_EqualSupNorm */
Definition: cudd.h:264
#define Cudd_IsConstant(node)
Definition: cudd.h:328
#define statLine(dd)
Definition: cuddInt.h:990
#define cuddV(node)
Definition: cuddInt.h:641
int Cudd_EqualSupNorm(DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr)
Definition: cuddInt.c:17044
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:297
FILE * out
Definition: cuddInt.h:423
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
#define cuddT(node)
Definition: cuddInt.h:609
#define ddEqualVal(x, y, e)
Definition: cuddInt.h:814
#define cuddI(dd, index)
Definition: cuddInt.h:659
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329

◆ Cudd_EquivDC()

int Cudd_EquivDC ( DdManager dd,
DdNode F,
DdNode G,
DdNode D 
)

Function********************************************************************

Synopsis [Tells whether F and G are identical wherever D is 0.]

Description [Tells whether F and G are identical wherever D is 0. F and G are either two ADDs or two BDDs. D is either a 0-1 ADD or a BDD. The function returns 1 if F and G are equivalent, and 0 otherwise. No new nodes are created.]

SideEffects [None]

SeeAlso [Cudd_bddLeqUnless]

Definition at line 16770 of file cuddInt.c.

16775  {
16776  DdNode *tmp, *One, *Gr, *Dr;
16777  DdNode *Fv, *Fvn, *Gv, *Gvn, *Dv, *Dvn;
16778  int res;
16779  unsigned int flevel, glevel, dlevel, top;
16780 
16781  One = DD_ONE(dd);
16782 
16783  statLine(dd);
16784  /* Check terminal cases. */
16785  if (D == One || F == G) return(1);
16786  if (D == Cudd_Not(One) || D == DD_ZERO(dd) || F == Cudd_Not(G)) return(0);
16787 
16788  /* From now on, D is non-constant. */
16789 
16790  /* Normalize call to increase cache efficiency. */
16791  if (F > G) {
16792  tmp = F;
16793  F = G;
16794  G = tmp;
16795  }
16796  if (Cudd_IsComplement(F)) {
16797  F = Cudd_Not(F);
16798  G = Cudd_Not(G);
16799  }
16800 
16801  /* From now on, F is regular. */
16802 
16803  /* Check cache. */
16804  tmp = cuddCacheLookup(dd,DD_EQUIV_DC_TAG,F,G,D);
16805  if (tmp != NULL) return(tmp == One);
16806 
16807  /* Find splitting variable. */
16808  flevel = cuddI(dd,F->index);
16809  Gr = Cudd_Regular(G);
16810  glevel = cuddI(dd,Gr->index);
16811  top = ddMin(flevel,glevel);
16812  Dr = Cudd_Regular(D);
16813  dlevel = dd->perm[Dr->index];
16814  top = ddMin(top,dlevel);
16815 
16816  /* Compute cofactors. */
16817  if (top == flevel) {
16818  Fv = cuddT(F);
16819  Fvn = cuddE(F);
16820  } else {
16821  Fv = Fvn = F;
16822  }
16823  if (top == glevel) {
16824  Gv = cuddT(Gr);
16825  Gvn = cuddE(Gr);
16826  if (G != Gr) {
16827  Gv = Cudd_Not(Gv);
16828  Gvn = Cudd_Not(Gvn);
16829  }
16830  } else {
16831  Gv = Gvn = G;
16832  }
16833  if (top == dlevel) {
16834  Dv = cuddT(Dr);
16835  Dvn = cuddE(Dr);
16836  if (D != Dr) {
16837  Dv = Cudd_Not(Dv);
16838  Dvn = Cudd_Not(Dvn);
16839  }
16840  } else {
16841  Dv = Dvn = D;
16842  }
16843 
16844  /* Solve recursively. */
16845  res = Cudd_EquivDC(dd,Fv,Gv,Dv);
16846  if (res != 0) {
16847  res = Cudd_EquivDC(dd,Fvn,Gvn,Dvn);
16848  }
16849  cuddCacheInsert(dd,DD_EQUIV_DC_TAG,F,G,D,(res) ? One : Cudd_Not(One));
16850 
16851  return(res);
16852 
16853  } /* end of Cudd_EquivDC */
int Cudd_EquivDC(DdManager *dd, DdNode *F, DdNode *G, DdNode *D)
Definition: cuddInt.c:16770
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:4413
#define Cudd_Regular(node)
Definition: cudd.h:373
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
#define DD_EQUIV_DC_TAG
Definition: cuddInt.h:183
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddInt.c:4283
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ Cudd_FirstCube()

DdGen* Cudd_FirstCube ( DdManager dd,
DdNode f,
int **  cube,
CUDD_VALUE_TYPE value 
)

Function********************************************************************

Synopsis [Finds the first cube of a decision diagram.]

Description [Defines an iterator on the onset of a decision diagram and finds its first cube. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise.

A cube is represented as an array of literals, which are integers in {0, 1, 2}; 0 represents a complemented literal, 1 represents an uncomplemented literal, and 2 stands for don't care. The enumeration produces a disjoint cover of the function associated with the diagram. The size of the array equals the number of variables in the manager at the time Cudd_FirstCube is called.

For each cube, a value is also returned. This value is always 1 for a BDD, while it may be different from 1 for an ADD. For BDDs, the offset is the set of cubes whose value is the logical zero. For ADDs, the offset is the set of cubes whose value is the background value. The cubes of the offset are not enumerated.]

SideEffects [The first cube and its value are returned as side effects.]

SeeAlso [Cudd_ForeachCube Cudd_NextCube Cudd_GenFree Cudd_IsGenEmpty Cudd_FirstNode]

Definition at line 22267 of file cuddInt.c.

22272 {
22273 DdGen *gen;
22274 DdNode *top, *treg, *next, *nreg, *prev, *preg;
22275 int i;
22276 int nvars;
22277 
22278 /* Sanity Check. */
22279 if (dd == NULL || f == NULL) return(NULL);
22280 
22281 /* Allocate generator an initialize it. */
22282 gen = ALLOC(DdGen,1);
22283 if (gen == NULL) {
22285 return(NULL);
22286 }
22287 
22288 gen->manager = dd;
22289 gen->type = CUDD_GEN_CUBES;
22290 gen->status = CUDD_GEN_EMPTY;
22291 gen->gen.cubes.cube = NULL;
22292 gen->gen.cubes.value = DD_ZERO_VAL;
22293 gen->stack.sp = 0;
22294 gen->stack.stack = NULL;
22295 gen->node = NULL;
22296 
22297 nvars = dd->size;
22298 gen->gen.cubes.cube = ALLOC(int,nvars);
22299 if (gen->gen.cubes.cube == NULL) {
22301 FREE(gen);
22302 return(NULL);
22303 }
22304 for (i = 0; i < nvars; i++) gen->gen.cubes.cube[i] = 2;
22305 
22306 /* The maximum stack depth is one plus the number of variables.
22307 ** because a path may have nodes at all levels, including the
22308 ** constant level.
22309 */
22310 gen->stack.stack = ALLOC(DdNodePtr, nvars+1);
22311 if (gen->stack.stack == NULL) {
22313 FREE(gen->gen.cubes.cube);
22314 FREE(gen);
22315 return(NULL);
22316 }
22317 for (i = 0; i <= nvars; i++) gen->stack.stack[i] = NULL;
22318 
22319 /* Find the first cube of the onset. */
22320 gen->stack.stack[gen->stack.sp] = f; gen->stack.sp++;
22321 
22322 while (1) {
22323 top = gen->stack.stack[gen->stack.sp-1];
22324 treg = Cudd_Regular(top);
22325 if (!cuddIsConstant(treg)) {
22326 /* Take the else branch first. */
22327 gen->gen.cubes.cube[treg->index] = 0;
22328 next = cuddE(treg);
22329 if (top != treg) next = Cudd_Not(next);
22330 gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++;
22331 } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) {
22332 /* Backtrack */
22333 while (1) {
22334 if (gen->stack.sp == 1) {
22335 /* The current node has no predecessor. */
22336 gen->status = CUDD_GEN_EMPTY;
22337 gen->stack.sp--;
22338 goto done;
22339 }
22340 prev = gen->stack.stack[gen->stack.sp-2];
22341 preg = Cudd_Regular(prev);
22342 nreg = cuddT(preg);
22343 if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;}
22344 if (next != top) { /* follow the then branch next */
22345 gen->gen.cubes.cube[preg->index] = 1;
22346 gen->stack.stack[gen->stack.sp-1] = next;
22347 break;
22348 }
22349 /* Pop the stack and try again. */
22350 gen->gen.cubes.cube[preg->index] = 2;
22351 gen->stack.sp--;
22352 top = gen->stack.stack[gen->stack.sp-1];
22353 treg = Cudd_Regular(top);
22354 }
22355 } else {
22356 gen->status = CUDD_GEN_NONEMPTY;
22357 gen->gen.cubes.value = cuddV(top);
22358 goto done;
22359 }
22360 }
22361 
22362 done:
22363 *cube = gen->gen.cubes.cube;
22364 *value = gen->gen.cubes.value;
22365 return(gen);
22366 
22367 } /* end of Cudd_FirstCube */
DdNode * node
Definition: cuddInt.h:227
int type
Definition: cuddInt.h:208
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define FREE(obj)
Definition: util.h:80
int size
Definition: cuddInt.h:345
#define Cudd_Regular(node)
Definition: cudd.h:373
Definition: cuddInt.h:206
#define DD_ZERO_VAL
Definition: cuddInt.h:109
#define CUDD_GEN_NONEMPTY
Definition: cuddInt.h:199
#define cuddV(node)
Definition: cuddInt.h:641
DdNode ** stack
Definition: cuddInt.h:225
#define ALLOC(type, num)
Definition: util.h:76
DdManager * manager
Definition: cuddInt.h:207
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
struct DdGen::@1::@3 cubes
#define CUDD_GEN_EMPTY
Definition: cuddInt.h:198
DdHalfWord index
Definition: cudd.h:265
#define CUDD_GEN_CUBES
Definition: cuddInt.h:194
union DdGen::@1 gen
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdNode * background
Definition: cuddInt.h:333
int status
Definition: cuddInt.h:209

◆ Cudd_FirstNode()

DdGen* Cudd_FirstNode ( DdManager dd,
DdNode f,
DdNode **  node 
)

Function********************************************************************

Synopsis [Finds the first node of a decision diagram.]

Description [Defines an iterator on the nodes of a decision diagram and finds its first node. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise. The nodes are enumerated in a reverse topological order, so that a node is always preceded in the enumeration by its descendants.]

SideEffects [The first node is returned as a side effect.]

SeeAlso [Cudd_ForeachNode Cudd_NextNode Cudd_GenFree Cudd_IsGenEmpty Cudd_FirstCube]

Definition at line 22723 of file cuddInt.c.

22727 {
22728 DdGen *gen;
22729 int size;
22730 
22731 /* Sanity Check. */
22732 if (dd == NULL || f == NULL) return(NULL);
22733 
22734 /* Allocate generator an initialize it. */
22735 gen = ALLOC(DdGen,1);
22736 if (gen == NULL) {
22738 return(NULL);
22739 }
22740 
22741 gen->manager = dd;
22742 gen->type = CUDD_GEN_NODES;
22743 gen->status = CUDD_GEN_EMPTY;
22744 gen->stack.sp = 0;
22745 gen->node = NULL;
22746 
22747 /* Collect all the nodes on the generator stack for later perusal. */
22748 gen->stack.stack = cuddNodeArray(Cudd_Regular(f), &size);
22749 if (gen->stack.stack == NULL) {
22750 FREE(gen);
22752 return(NULL);
22753 }
22754 gen->gen.nodes.size = size;
22755 
22756 /* Find the first node. */
22757 if (gen->stack.sp < gen->gen.nodes.size) {
22758 gen->status = CUDD_GEN_NONEMPTY;
22759 gen->node = gen->stack.stack[gen->stack.sp];
22760 *node = gen->node;
22761 }
22762 
22763 return(gen);
22764 
22765 } /* end of Cudd_FirstNode */
DdNode * node
Definition: cuddInt.h:227
int type
Definition: cuddInt.h:208
#define FREE(obj)
Definition: util.h:80
#define CUDD_GEN_NODES
Definition: cuddInt.h:196
struct DdGen::@1::@5 nodes
#define Cudd_Regular(node)
Definition: cudd.h:373
Definition: cuddInt.h:206
#define CUDD_GEN_NONEMPTY
Definition: cuddInt.h:199
DdNode ** stack
Definition: cuddInt.h:225
#define ALLOC(type, num)
Definition: util.h:76
DdManager * manager
Definition: cuddInt.h:207
#define CUDD_GEN_EMPTY
Definition: cuddInt.h:198
union DdGen::@1 gen
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
int status
Definition: cuddInt.h:209
DdNodePtr * cuddNodeArray(DdNode *f, int *n)
Definition: cuddInt.c:23067

◆ Cudd_FirstPrime()

DdGen* Cudd_FirstPrime ( DdManager dd,
DdNode l,
DdNode u,
int **  cube 
)

Function********************************************************************

Synopsis [Finds the first prime of a Boolean function.]

Description [Defines an iterator on a pair of BDDs describing a (possibly incompletely specified) Boolean functions and finds the first cube of a cover of the function. Returns a generator that contains the information necessary to continue the enumeration if successful; NULL otherwise.

The two argument BDDs are the lower and upper bounds of an interval. It is a mistake to call this function with a lower bound that is not less than or equal to the upper bound.

A cube is represented as an array of literals, which are integers in {0, 1, 2}; 0 represents a complemented literal, 1 represents an uncomplemented literal, and 2 stands for don't care. The enumeration produces a prime and irredundant cover of the function associated with the two BDDs. The size of the array equals the number of variables in the manager at the time Cudd_FirstCube is called.

This iterator can only be used on BDDs.]

SideEffects [The first cube is returned as side effect.]

SeeAlso [Cudd_ForeachPrime Cudd_NextPrime Cudd_GenFree Cudd_IsGenEmpty Cudd_FirstCube Cudd_FirstNode]

Definition at line 22497 of file cuddInt.c.

22502 {
22503 DdGen *gen;
22504 DdNode *implicant, *prime, *tmp;
22505 int length, result;
22506 
22507 /* Sanity Check. */
22508 if (dd == NULL || l == NULL || u == NULL) return(NULL);
22509 
22510 /* Allocate generator an initialize it. */
22511 gen = ALLOC(DdGen,1);
22512 if (gen == NULL) {
22514 return(NULL);
22515 }
22516 
22517 gen->manager = dd;
22518 gen->type = CUDD_GEN_PRIMES;
22519 gen->status = CUDD_GEN_EMPTY;
22520 gen->gen.primes.cube = NULL;
22521 gen->gen.primes.ub = u;
22522 gen->stack.sp = 0;
22523 gen->stack.stack = NULL;
22524 gen->node = l;
22525 cuddRef(l);
22526 
22527 gen->gen.primes.cube = ALLOC(int,dd->size);
22528 if (gen->gen.primes.cube == NULL) {
22530 FREE(gen);
22531 return(NULL);
22532 }
22533 
22534 if (gen->node == Cudd_ReadLogicZero(dd)) {
22535 gen->status = CUDD_GEN_EMPTY;
22536 } else {
22537 implicant = Cudd_LargestCube(dd,gen->node,&length);
22538 if (implicant == NULL) {
22539 Cudd_RecursiveDeref(dd,gen->node);
22540 FREE(gen->gen.primes.cube);
22541 FREE(gen);
22542 return(NULL);
22543 }
22544 cuddRef(implicant);
22545 prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub);
22546 if (prime == NULL) {
22547 Cudd_RecursiveDeref(dd,gen->node);
22548 Cudd_RecursiveDeref(dd,implicant);
22549 FREE(gen->gen.primes.cube);
22550 FREE(gen);
22551 return(NULL);
22552 }
22553 cuddRef(prime);
22554 Cudd_RecursiveDeref(dd,implicant);
22555 tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime));
22556 if (tmp == NULL) {
22557 Cudd_RecursiveDeref(dd,gen->node);
22558 Cudd_RecursiveDeref(dd,prime);
22559 FREE(gen->gen.primes.cube);
22560 FREE(gen);
22561 return(NULL);
22562 }
22563 cuddRef(tmp);
22564 Cudd_RecursiveDeref(dd,gen->node);
22565 gen->node = tmp;
22566 result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube);
22567 if (result == 0) {
22568 Cudd_RecursiveDeref(dd,gen->node);
22569 Cudd_RecursiveDeref(dd,prime);
22570 FREE(gen->gen.primes.cube);
22571 FREE(gen);
22572 return(NULL);
22573 }
22574 Cudd_RecursiveDeref(dd,prime);
22575 gen->status = CUDD_GEN_NONEMPTY;
22576 }
22577 *cube = gen->gen.primes.cube;
22578 return(gen);
22579 
22580 } /* end of Cudd_FirstPrime */
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3114
#define cuddRef(n)
Definition: cuddInt.h:557
DdNode * node
Definition: cuddInt.h:227
int type
Definition: cuddInt.h:208
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define FREE(obj)
Definition: util.h:80
int Cudd_BddToCubeArray(DdManager *dd, DdNode *cube, int *array)
Definition: cuddInt.c:22669
int size
Definition: cuddInt.h:345
DdNode * Cudd_ReadLogicZero(DdManager *dd)
Definition: cuddInt.c:1738
DdNode * Cudd_LargestCube(DdManager *manager, DdNode *f, int *length)
Definition: cuddInt.c:16616
Definition: cuddInt.h:206
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
#define CUDD_GEN_NONEMPTY
Definition: cuddInt.h:199
DdNode ** stack
Definition: cuddInt.h:225
#define ALLOC(type, num)
Definition: util.h:76
DdManager * manager
Definition: cuddInt.h:207
struct DdGen::@1::@4 primes
DdNode * Cudd_bddMakePrime(DdManager *dd, DdNode *cube, DdNode *f)
Definition: cuddInt.c:17112
#define CUDD_GEN_EMPTY
Definition: cuddInt.h:198
static int result
Definition: cuddInt.c:7466
union DdGen::@1 gen
#define CUDD_GEN_PRIMES
Definition: cuddInt.h:195
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
int status
Definition: cuddInt.h:209

◆ Cudd_FreeTree()

void Cudd_FreeTree ( DdManager dd)

Function********************************************************************

Synopsis [Frees the variable group tree of the manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_SetTree Cudd_ReadTree Cudd_FreeZddTree]

Definition at line 1807 of file cuddInt.c.

1809 {
1810  if (dd->tree != NULL) {
1811  Mtr_FreeTree(dd->tree);
1812  dd->tree = NULL;
1813  }
1814  return;
1815 
1816 } /* end of Cudd_FreeTree */
void Mtr_FreeTree(MtrNode *node)
Definition: mtr.c:187
MtrNode * tree
Definition: cuddInt.h:408

◆ Cudd_FreeZddTree()

void Cudd_FreeZddTree ( DdManager dd)

Function********************************************************************

Synopsis [Frees the variable group tree of the manager.]

Description []

SideEffects [None]

SeeAlso [Cudd_SetZddTree Cudd_ReadZddTree Cudd_FreeTree]

Definition at line 1831 of file cuddInt.c.

1833 {
1834  if (dd->treeZ != NULL) {
1835  Mtr_FreeTree(dd->treeZ);
1836  dd->treeZ = NULL;
1837  }
1838  return;
1839 
1840 } /* end of Cudd_FreeZddTree */
void Mtr_FreeTree(MtrNode *node)
Definition: mtr.c:187
MtrNode * treeZ
Definition: cuddInt.h:409

◆ Cudd_GenFree()

int Cudd_GenFree ( DdGen gen)

Function********************************************************************

Synopsis [Frees a CUDD generator.]

Description [Frees a CUDD generator. Always returns 0, so that it can be used in mis-like foreach constructs.]

SideEffects [None]

SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_FirstNode Cudd_NextNode Cudd_IsGenEmpty]

Definition at line 22814 of file cuddInt.c.

22816 {
22817 if (gen == NULL) return(0);
22818 switch (gen->type) {
22819 case CUDD_GEN_CUBES:
22820 case CUDD_GEN_ZDD_PATHS:
22821 FREE(gen->gen.cubes.cube);
22822 FREE(gen->stack.stack);
22823 break;
22824 case CUDD_GEN_PRIMES:
22825 FREE(gen->gen.primes.cube);
22826 Cudd_RecursiveDeref(gen->manager,gen->node);
22827 break;
22828 case CUDD_GEN_NODES:
22829 FREE(gen->stack.stack);
22830 break;
22831 default:
22832 return(0);
22833 }
22834 FREE(gen);
22835 return(0);
22836 
22837 } /* end of Cudd_GenFree */
DdNode * node
Definition: cuddInt.h:227
int type
Definition: cuddInt.h:208
#define FREE(obj)
Definition: util.h:80
#define CUDD_GEN_ZDD_PATHS
Definition: cuddInt.h:197
#define CUDD_GEN_NODES
Definition: cuddInt.h:196
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
DdNode ** stack
Definition: cuddInt.h:225
DdManager * manager
Definition: cuddInt.h:207
struct DdGen::@1::@4 primes
struct DdGen::@1::@3 cubes
#define CUDD_GEN_CUBES
Definition: cuddInt.h:194
union DdGen::@1 gen
#define CUDD_GEN_PRIMES
Definition: cuddInt.h:195

◆ Cudd_Init()

DdManager* Cudd_Init ( unsigned int  numVars,
unsigned int  numVarsZ,
unsigned int  numSlots,
unsigned int  cacheSize,
unsigned long  maxMemory 
)

CFile***********************************************************************

FileName [cuddInit.c]

PackageName [cudd]

Synopsis [Functions to initialize and shut down the DD manager.]

Description [External procedures included in this module:

Internal procedures included in this module:

]

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Creates a new DD manager.]

Description [Creates a new DD manager, initializes the table, the basic constants and the projection functions. If maxMemory is 0, Cudd_Init decides suitable values for the maximum size of the cache and for the limit for fast unique table growth based on the available memory. Returns a pointer to the manager if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_Quit]

Definition at line 10544 of file cuddInt.c.

10550 {
10551  DdManager *unique;
10552  int i,result;
10553  DdNode *one, *zero;
10554  unsigned int maxCacheSize;
10555  unsigned int looseUpTo;
10556  extern DD_OOMFP MMoutOfMemory;
10557  DD_OOMFP saveHandler;
10558 
10559  if (maxMemory == 0) {
10560  maxMemory = getSoftDataLimit();
10561  }
10562  looseUpTo = (unsigned int) ((maxMemory / sizeof(DdNode)) /
10564  unique = cuddInitTable(numVars,numVarsZ,numSlots,looseUpTo);
10565  if (unique == NULL) return(NULL);
10566  unique->maxmem = (unsigned long) maxMemory / 10 * 9;
10567  maxCacheSize = (unsigned int) ((maxMemory / sizeof(DdCache)) /
10569  result = cuddInitCache(unique,cacheSize,maxCacheSize);
10570  if (result == 0) return(NULL);
10571 
10572  saveHandler = MMoutOfMemory;
10573  MMoutOfMemory = Cudd_OutOfMem;
10574  unique->stash = ALLOC(char,(maxMemory / DD_STASH_FRACTION) + 4);
10575  MMoutOfMemory = saveHandler;
10576  if (unique->stash == NULL) {
10577  (void) fprintf(unique->err,"Unable to set aside memory\n");
10578  }
10579 
10580  /* Initialize constants. */
10581  unique->one = cuddUniqueConst(unique,1.0);
10582  if (unique->one == NULL) return(0);
10583  cuddRef(unique->one);
10584  unique->zero = cuddUniqueConst(unique,0.0);
10585  if (unique->zero == NULL) return(0);
10586  cuddRef(unique->zero);
10587 #ifdef HAVE_IEEE_754
10588  if (DD_PLUS_INF_VAL != DD_PLUS_INF_VAL * 3 ||
10590  (void) fprintf(unique->err,"Warning: Crippled infinite values\n");
10591  (void) fprintf(unique->err,"Recompile without -DHAVE_IEEE_754\n");
10592  }
10593 #endif
10594  unique->plusinfinity = cuddUniqueConst(unique,DD_PLUS_INF_VAL);
10595  if (unique->plusinfinity == NULL) return(0);
10596  cuddRef(unique->plusinfinity);
10598  if (unique->minusinfinity == NULL) return(0);
10599  cuddRef(unique->minusinfinity);
10600  unique->background = unique->zero;
10601 
10602  /* The logical zero is different from the CUDD_VALUE_TYPE zero! */
10603  one = unique->one;
10604  zero = Cudd_Not(one);
10605  /* Create the projection functions. */
10606  unique->vars = ALLOC(DdNodePtr,unique->maxSize);
10607  if (unique->vars == NULL) {
10608  unique->errorCode = CUDD_MEMORY_OUT;
10609  return(NULL);
10610  }
10611  for (i = 0; i < unique->size; i++) {
10612  unique->vars[i] = cuddUniqueInter(unique,i,one,zero);
10613  if (unique->vars[i] == NULL) return(0);
10614  cuddRef(unique->vars[i]);
10615  }
10616 
10617  if (unique->sizeZ)
10618  cuddZddInitUniv(unique);
10619 
10620  unique->memused += sizeof(DdNode *) * unique->maxSize;
10621 
10622  return(unique);
10623 
10624 } /* end of Cudd_Init */
#define cuddRef(n)
Definition: cuddInt.h:557
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define DD_MAX_CACHE_FRACTION
Definition: cuddInt.h:141
int size
Definition: cuddInt.h:345
static DdNode * one
Definition: cuddInt.c:16562
#define DD_STASH_FRACTION
Definition: cuddInt.h:143
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
Definition: cuddInt.c:20837
DdNode * zero
Definition: cuddInt.h:330
#define DD_MAX_LOOSE_FRACTION
Definition: cuddInt.h:139
FILE * err
Definition: cuddInt.h:424
int cuddZddInitUniv(DdManager *zdd)
Definition: cuddInt.c:10668
#define DD_PLUS_INF_VAL
Definition: cuddInt.h:118
int cuddInitCache(DdManager *unique, unsigned int cacheSize, unsigned int maxCacheSize)
Definition: cuddInt.c:4198
void(* DD_OOMFP)(long)
Definition: cudd.h:300
char * stash
Definition: cuddInt.h:382
#define ALLOC(type, num)
Definition: util.h:76
int maxSize
Definition: cuddInt.h:347
unsigned long getSoftDataLimit(void)
Definition: util.c:198
void(* MMoutOfMemory)(long)
Definition: util.c:105
unsigned long memused
Definition: cuddInt.h:429
int sizeZ
Definition: cuddInt.h:346
static int result
Definition: cuddInt.c:7466
DdNode ** vars
Definition: cuddInt.h:373
DdManager * cuddInitTable(unsigned int numVars, unsigned int numVarsZ, unsigned int numSlots, unsigned int looseUpTo)
Definition: cuddInt.c:19738
DdNode * one
Definition: cuddInt.h:329
DdNode * plusinfinity
Definition: cuddInt.h:331
void Cudd_OutOfMem(long size)
Definition: cuddInt.c:22982
static DdNode * zero
Definition: cuddInt.c:16562
unsigned long maxmem
Definition: cuddInt.h:430
DdNode * minusinfinity
Definition: cuddInt.h:332
#define DD_MINUS_INF_VAL
Definition: cuddInt.h:122
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdNode * background
Definition: cuddInt.h:333

◆ Cudd_IsGenEmpty()

int Cudd_IsGenEmpty ( DdGen gen)

Function********************************************************************

Synopsis [Queries the status of a generator.]

Description [Queries the status of a generator. Returns 1 if the generator is empty or NULL; 0 otherswise.]

SideEffects [None]

SeeAlso [Cudd_ForeachCube Cudd_ForeachNode Cudd_FirstCube Cudd_NextCube Cudd_FirstNode Cudd_NextNode Cudd_GenFree]

Definition at line 22854 of file cuddInt.c.

22856 {
22857 if (gen == NULL) return(1);
22858 return(gen->status == CUDD_GEN_EMPTY);
22859 
22860 } /* end of Cudd_IsGenEmpty */
#define CUDD_GEN_EMPTY
Definition: cuddInt.h:198
int status
Definition: cuddInt.h:209

◆ Cudd_IterDerefBdd()

void Cudd_IterDerefBdd ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Decreases the reference count of BDD node n.]

Description [Decreases the reference count of node n. If n dies, recursively decreases the reference counts of its children. It is used to dispose of a BDD that is no longer needed. It is more efficient than Cudd_RecursiveDeref, but it cannot be used on ADDs. The greater efficiency comes from being able to assume that no constant node will ever die as a result of a call to this procedure.]

SideEffects [None]

SeeAlso [Cudd_RecursiveDeref Cudd_DelayedDerefBdd]

Definition at line 14090 of file cuddInt.c.

14093 {
14094  DdNode *N;
14095  int ord;
14096  DdNodePtr *stack = table->stack;
14097  int SP = 1;
14098 
14099  unsigned int live = table->keys - table->dead;
14100  if (live > table->peakLiveNodes) {
14101  table->peakLiveNodes = live;
14102  }
14103 
14104  N = Cudd_Regular(n);
14105 
14106  do {
14107 #ifdef DD_DEBUG
14108  assert(N->ref != 0);
14109 #endif
14110 
14111  if (N->ref == 1) {
14112  N->ref = 0;
14113  table->dead++;
14114 #ifdef DD_STATS
14115  table->nodesDropped++;
14116 #endif
14117  ord = table->perm[N->index];
14118  stack[SP++] = Cudd_Regular(cuddE(N));
14119  table->subtables[ord].dead++;
14120  N = cuddT(N);
14121  } else {
14122  cuddSatDec(N->ref);
14123  N = stack[--SP];
14124  }
14125  } while (SP != 0);
14126 
14127 } /* end of Cudd_IterDerefBdd */
DdHalfWord ref
Definition: cudd.h:266
unsigned int peakLiveNodes
Definition: cuddInt.h:445
Definition: cudd.h:264
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:373
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode ** stack
Definition: cuddInt.h:364
unsigned int dead
Definition: cuddInt.h:355
unsigned int keys
Definition: cuddInt.h:353
unsigned int dead
Definition: cuddInt.h:316
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
int * perm
Definition: cuddInt.h:369

◆ Cudd_LargestCube()

DdNode* Cudd_LargestCube ( DdManager manager,
DdNode f,
int *  length 
)

AutomaticEnd Function********************************************************************

Synopsis [Finds a largest cube in a DD.]

Description [Finds a largest cube in a DD. f is the DD we want to get the largest cube for. The problem is translated into the one of finding a shortest path in f, when both THEN and ELSE arcs are assumed to have unit length. This yields a largest cube in the disjoint cover corresponding to the DD. Therefore, it is not necessarily the largest implicant of f. Returns the largest cube as a BDD.]

SideEffects [The number of literals of the cube is returned in the location pointed by length if it is non-null.]

SeeAlso [Cudd_ShortestPath]

Definition at line 16616 of file cuddInt.c.

16620  {
16621  register DdNode *F;
16622  st_table *visited;
16623  DdNode *sol;
16624  cuddPathPair *rootPair;
16625  int complement, cost;
16626 
16627  one = DD_ONE(manager);
16628  zero = DD_ZERO(manager);
16629 
16630  if (f == Cudd_Not(one) || f == zero) {
16631  if (length != NULL) {
16632  *length = DD_BIGGY;
16633  }
16634  return(Cudd_Not(one));
16635  }
16636  /* From this point on, a path exists. */
16637 
16638  do {
16639  manager->reordered = 0;
16640 
16641  /* Initialize visited table. */
16642  visited = st_init_table(st_ptrcmp, st_ptrhash);
16643 
16644  /* Now get the length of the shortest path(s) from f to 1. */
16645  (void) getLargest(f, visited);
16646 
16647  complement = Cudd_IsComplement(f);
16648 
16649  F = Cudd_Regular(f);
16650 
16651  if (!st_lookup(visited, F, &rootPair)) return(NULL);
16652 
16653  if (complement) {
16654  cost = rootPair->neg;
16655  } else {
16656  cost = rootPair->pos;
16657  }
16658 
16659  /* Recover an actual shortest path. */
16660  sol = getCube(manager,visited,f,cost);
16661 
16662  st_foreach(visited, freePathPair, NULL);
16663  st_free_table(visited);
16664 
16665  } while (manager->reordered == 1);
16666 
16667  if (length != NULL) {
16668  *length = cost;
16669  }
16670  return(sol);
16671 
16672  } /* end of Cudd_LargestCube */
int st_lookup(st_table *, void *, void *)
Definition: st.c:271
Definition: st.h:60
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
int st_foreach(st_table *, ST_PFSR, char *)
Definition: st.c:487
static enum st_retval freePathPair(char *key, char *value, char *arg)
Definition: cuddInt.c:17213
static DdNode * one
Definition: cuddInt.c:16562
void st_free_table(st_table *)
Definition: st.c:237
#define Cudd_Regular(node)
Definition: cudd.h:373
int reordered
Definition: cuddInt.h:392
#define Cudd_IsComplement(node)
Definition: cudd.h:401
int st_ptrcmp(const char *, const char *)
Definition: st.c:585
#define DD_BIGGY
Definition: cuddInt.c:16539
st_table * st_init_table(ST_PFICPCP, ST_PFICPI)
Definition: st.c:148
static cuddPathPair getLargest(DdNode *root, st_table *visited)
Definition: cuddInt.c:17347
int st_ptrhash(char *, int)
Definition: st.c:547
static DdNode * zero
Definition: cuddInt.c:16562
static DdNode * getCube(DdManager *manager, st_table *visited, DdNode *f, int cost)
Definition: cuddInt.c:17435
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ Cudd_NextCube()

int Cudd_NextCube ( DdGen gen,
int **  cube,
CUDD_VALUE_TYPE value 
)

Function********************************************************************

Synopsis [Generates the next cube of a decision diagram onset.]

Description [Generates the next cube of a decision diagram onset, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]

SideEffects [The cube and its value are returned as side effects. The generator is modified.]

SeeAlso [Cudd_ForeachCube Cudd_FirstCube Cudd_GenFree Cudd_IsGenEmpty Cudd_NextNode]

Definition at line 22386 of file cuddInt.c.

22390 {
22391 DdNode *top, *treg, *next, *nreg, *prev, *preg;
22392 DdManager *dd = gen->manager;
22393 
22394 /* Backtrack from previously reached terminal node. */
22395 while (1) {
22396 if (gen->stack.sp == 1) {
22397 /* The current node has no predecessor. */
22398 gen->status = CUDD_GEN_EMPTY;
22399 gen->stack.sp--;
22400 goto done;
22401 }
22402 top = gen->stack.stack[gen->stack.sp-1];
22403 treg = Cudd_Regular(top);
22404 prev = gen->stack.stack[gen->stack.sp-2];
22405 preg = Cudd_Regular(prev);
22406 nreg = cuddT(preg);
22407 if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;}
22408 if (next != top) { /* follow the then branch next */
22409 gen->gen.cubes.cube[preg->index] = 1;
22410 gen->stack.stack[gen->stack.sp-1] = next;
22411 break;
22412 }
22413 /* Pop the stack and try again. */
22414 gen->gen.cubes.cube[preg->index] = 2;
22415 gen->stack.sp--;
22416 }
22417 
22418 while (1) {
22419 top = gen->stack.stack[gen->stack.sp-1];
22420 treg = Cudd_Regular(top);
22421 if (!cuddIsConstant(treg)) {
22422 /* Take the else branch first. */
22423 gen->gen.cubes.cube[treg->index] = 0;
22424 next = cuddE(treg);
22425 if (top != treg) next = Cudd_Not(next);
22426 gen->stack.stack[gen->stack.sp] = next; gen->stack.sp++;
22427 } else if (top == Cudd_Not(DD_ONE(dd)) || top == dd->background) {
22428 /* Backtrack */
22429 while (1) {
22430 if (gen->stack.sp == 1) {
22431 /* The current node has no predecessor. */
22432 gen->status = CUDD_GEN_EMPTY;
22433 gen->stack.sp--;
22434 goto done;
22435 }
22436 prev = gen->stack.stack[gen->stack.sp-2];
22437 preg = Cudd_Regular(prev);
22438 nreg = cuddT(preg);
22439 if (prev != preg) {next = Cudd_Not(nreg);} else {next = nreg;}
22440 if (next != top) { /* follow the then branch next */
22441 gen->gen.cubes.cube[preg->index] = 1;
22442 gen->stack.stack[gen->stack.sp-1] = next;
22443 break;
22444 }
22445 /* Pop the stack and try again. */
22446 gen->gen.cubes.cube[preg->index] = 2;
22447 gen->stack.sp--;
22448 top = gen->stack.stack[gen->stack.sp-1];
22449 treg = Cudd_Regular(top);
22450 }
22451 } else {
22452 gen->status = CUDD_GEN_NONEMPTY;
22453 gen->gen.cubes.value = cuddV(top);
22454 goto done;
22455 }
22456 }
22457 
22458 done:
22459 if (gen->status == CUDD_GEN_EMPTY) return(0);
22460 *cube = gen->gen.cubes.cube;
22461 *value = gen->gen.cubes.value;
22462 return(1);
22463 
22464 } /* end of Cudd_NextCube */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_Regular(node)
Definition: cudd.h:373
#define CUDD_GEN_NONEMPTY
Definition: cuddInt.h:199
#define cuddV(node)
Definition: cuddInt.h:641
DdNode ** stack
Definition: cuddInt.h:225
DdManager * manager
Definition: cuddInt.h:207
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
struct DdGen::@1::@3 cubes
#define CUDD_GEN_EMPTY
Definition: cuddInt.h:198
DdHalfWord index
Definition: cudd.h:265
union DdGen::@1 gen
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * background
Definition: cuddInt.h:333
int status
Definition: cuddInt.h:209

◆ Cudd_NextNode()

int Cudd_NextNode ( DdGen gen,
DdNode **  node 
)

Function********************************************************************

Synopsis [Finds the next node of a decision diagram.]

Description [Finds the node of a decision diagram, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]

SideEffects [The next node is returned as a side effect.]

SeeAlso [Cudd_ForeachNode Cudd_FirstNode Cudd_GenFree Cudd_IsGenEmpty Cudd_NextCube]

Definition at line 22782 of file cuddInt.c.

22785 {
22786 /* Find the next node. */
22787 gen->stack.sp++;
22788 if (gen->stack.sp < gen->gen.nodes.size) {
22789 gen->node = gen->stack.stack[gen->stack.sp];
22790 *node = gen->node;
22791 return(1);
22792 } else {
22793 gen->status = CUDD_GEN_EMPTY;
22794 return(0);
22795 }
22796 
22797 } /* end of Cudd_NextNode */
DdNode * node
Definition: cuddInt.h:227
struct DdGen::@1::@5 nodes
DdNode ** stack
Definition: cuddInt.h:225
#define CUDD_GEN_EMPTY
Definition: cuddInt.h:198
union DdGen::@1 gen
int status
Definition: cuddInt.h:209

◆ Cudd_NextPrime()

int Cudd_NextPrime ( DdGen gen,
int **  cube 
)

Function********************************************************************

Synopsis [Generates the next prime of a Boolean function.]

Description [Generates the next cube of a Boolean function, using generator gen. Returns 0 if the enumeration is completed; 1 otherwise.]

SideEffects [The cube and is returned as side effects. The generator is modified.]

SeeAlso [Cudd_ForeachPrime Cudd_FirstPrime Cudd_GenFree Cudd_IsGenEmpty Cudd_NextCube Cudd_NextNode]

Definition at line 22599 of file cuddInt.c.

22602 {
22603 DdNode *implicant, *prime, *tmp;
22604 DdManager *dd = gen->manager;
22605 int length, result;
22606 
22607 if (gen->node == Cudd_ReadLogicZero(dd)) {
22608 gen->status = CUDD_GEN_EMPTY;
22609 } else {
22610 implicant = Cudd_LargestCube(dd,gen->node,&length);
22611 if (implicant == NULL) {
22612 gen->status = CUDD_GEN_EMPTY;
22613 return(0);
22614 }
22615 cuddRef(implicant);
22616 prime = Cudd_bddMakePrime(dd,implicant,gen->gen.primes.ub);
22617 if (prime == NULL) {
22618 Cudd_RecursiveDeref(dd,implicant);
22619 gen->status = CUDD_GEN_EMPTY;
22620 return(0);
22621 }
22622 cuddRef(prime);
22623 Cudd_RecursiveDeref(dd,implicant);
22624 tmp = Cudd_bddAnd(dd,gen->node,Cudd_Not(prime));
22625 if (tmp == NULL) {
22626 Cudd_RecursiveDeref(dd,prime);
22627 gen->status = CUDD_GEN_EMPTY;
22628 return(0);
22629 }
22630 cuddRef(tmp);
22631 Cudd_RecursiveDeref(dd,gen->node);
22632 gen->node = tmp;
22633 result = Cudd_BddToCubeArray(dd,prime,gen->gen.primes.cube);
22634 if (result == 0) {
22635 Cudd_RecursiveDeref(dd,prime);
22636 gen->status = CUDD_GEN_EMPTY;
22637 return(0);
22638 }
22639 Cudd_RecursiveDeref(dd,prime);
22640 gen->status = CUDD_GEN_NONEMPTY;
22641 }
22642 if (gen->status == CUDD_GEN_EMPTY) return(0);
22643 *cube = gen->gen.primes.cube;
22644 return(1);
22645 
22646 } /* end of Cudd_NextPrime */
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3114
#define cuddRef(n)
Definition: cuddInt.h:557
DdNode * node
Definition: cuddInt.h:227
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
int Cudd_BddToCubeArray(DdManager *dd, DdNode *cube, int *array)
Definition: cuddInt.c:22669
DdNode * Cudd_ReadLogicZero(DdManager *dd)
Definition: cuddInt.c:1738
DdNode * Cudd_LargestCube(DdManager *manager, DdNode *f, int *length)
Definition: cuddInt.c:16616
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
#define CUDD_GEN_NONEMPTY
Definition: cuddInt.h:199
DdManager * manager
Definition: cuddInt.h:207
struct DdGen::@1::@4 primes
DdNode * Cudd_bddMakePrime(DdManager *dd, DdNode *cube, DdNode *f)
Definition: cuddInt.c:17112
#define CUDD_GEN_EMPTY
Definition: cuddInt.h:198
static int result
Definition: cuddInt.c:7466
union DdGen::@1 gen
int status
Definition: cuddInt.h:209

◆ Cudd_OutOfMem()

void Cudd_OutOfMem ( long  size)

Function********************************************************************

Synopsis [Warns that a memory allocation failed.]

Description [Warns that a memory allocation failed. This function can be used as replacement of MMout_of_memory to prevent the safe_mem functions of the util package from exiting when malloc returns NULL. One possible use is in case of discretionary allocations; for instance, the allocation of memory to enlarge the computed table.]

SideEffects [None]

SeeAlso []

Definition at line 22982 of file cuddInt.c.

22984 {
22985 (void) fflush(stdout);
22986 (void) fprintf(stderr, "\nunable to allocate %ld bytes\n", size);
22987 return;
22988 
22989 } /* end of Cudd_OutOfMem */

◆ Cudd_PrintLinear()

int Cudd_PrintLinear ( DdManager table)

AutomaticEnd Function********************************************************************

Synopsis [Prints the linear transform matrix.]

Description [Prints the linear transform matrix. Returns 1 in case of success; 0 otherwise.]

SideEffects [none]

SeeAlso []

Definition at line 12695 of file cuddInt.c.

12697 {
12698  int i,j,k;
12699  int retval;
12700  int nvars = table->linearSize;
12701  int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
12702  long word;
12703 
12704  for (i = 0; i < nvars; i++) {
12705  for (j = 0; j < wordsPerRow; j++) {
12706  word = table->linear[i*wordsPerRow + j];
12707  for (k = 0; k < BPL; k++) {
12708  retval = fprintf(table->out,"%ld",word & 1);
12709  if (retval == 0) return(0);
12710  word >>= 1;
12711  }
12712  }
12713  retval = fprintf(table->out,"\n");
12714  if (retval == 0) return(0);
12715  }
12716  return(1);
12717 
12718 } /* end of Cudd_PrintLinear */
#define BPL
Definition: cuddInt.c:12624
FILE * out
Definition: cuddInt.h:423
long * linear
Definition: cuddInt.h:378
int linearSize
Definition: cuddInt.h:376
#define LOGBPL
Definition: cuddInt.c:12625

◆ Cudd_Quit()

void Cudd_Quit ( DdManager unique)

Function********************************************************************

Synopsis [Deletes resources associated with a DD manager.]

Description [Deletes resources associated with a DD manager and resets the global statistical counters. (Otherwise, another manaqger subsequently created would inherit the stats of this one.)]

SideEffects [None]

SeeAlso [Cudd_Init]

Definition at line 10641 of file cuddInt.c.

10643 {
10644  if (unique->stash != NULL) FREE(unique->stash);
10645  cuddFreeTable(unique);
10646 
10647 } /* end of Cudd_Quit */
#define FREE(obj)
Definition: util.h:80
char * stash
Definition: cuddInt.h:382
void cuddFreeTable(DdManager *unique)
Definition: cuddInt.c:20050

◆ Cudd_Random()

long Cudd_Random ( void  )

Function********************************************************************

Synopsis [Portable random number generator.]

Description [Portable number generator based on ran2 from "Numerical Recipes in C." It is a long period (> 2 * 10^18) random number generator of L'Ecuyer with Bays-Durham shuffle. Returns a long integer uniformly distributed between 0 and 2147483561 (inclusive of the endpoint values). The random generator can be explicitly initialized by calling Cudd_Srandom. If no explicit initialization is performed, then the seed 1 is assumed.]

SideEffects [None]

SeeAlso [Cudd_Srandom]

Definition at line 22881 of file cuddInt.c.

22882 {
22883 int i; /* index in the shuffle table */
22884 long int w; /* work variable */
22885 
22886 /* cuddRand == 0 if the geneartor has not been initialized yet. */
22887 if (cuddRand == 0) Cudd_Srandom(1);
22888 
22889 /* Compute cuddRand = (cuddRand * LEQA1) % MODULUS1 avoiding
22890 ** overflows by Schrage's method.
22891 */
22892 w = cuddRand / LEQQ1;
22893 cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1;
22894 cuddRand += (cuddRand < 0) * MODULUS1;
22895 
22896 /* Compute cuddRand2 = (cuddRand2 * LEQA2) % MODULUS2 avoiding
22897 ** overflows by Schrage's method.
22898 */
22899 w = cuddRand2 / LEQQ2;
22900 cuddRand2 = LEQA2 * (cuddRand2 - w * LEQQ2) - w * LEQR2;
22901 cuddRand2 += (cuddRand2 < 0) * MODULUS2;
22902 
22903 /* cuddRand is shuffled with the Bays-Durham algorithm.
22904 ** shuffleSelect and cuddRand2 are combined to generate the output.
22905 */
22906 
22907 /* Pick one element from the shuffle table; "i" will be in the range
22908 ** from 0 to STAB_SIZE-1.
22909 */
22910 i = (int) (shuffleSelect / STAB_DIV);
22911 /* Mix the element of the shuffle table with the current iterate of
22912 ** the second sub-generator, and replace the chosen element of the
22913 ** shuffle table with the current iterate of the first sub-generator.
22914 */
22916 shuffleTable[i] = cuddRand;
22917 shuffleSelect += (shuffleSelect < 1) * (MODULUS1 - 1);
22918 /* Since shuffleSelect != 0, and we want to be able to return 0,
22919 ** here we subtract 1 before returning.
22920 */
22921 return(shuffleSelect - 1);
22922 
22923 } /* end of Cudd_Random */
#define LEQA2
Definition: cuddInt.c:22118
#define LEQQ1
Definition: cuddInt.c:22115
#define LEQR1
Definition: cuddInt.c:22116
static long shuffleTable[STAB_SIZE]
Definition: cuddInt.c:22146
#define MODULUS1
Definition: cuddInt.c:22113
#define STAB_DIV
Definition: cuddInt.c:22122
static long cuddRand2
Definition: cuddInt.c:22144
#define LEQQ2
Definition: cuddInt.c:22119
#define MODULUS2
Definition: cuddInt.c:22117
#define LEQA1
Definition: cuddInt.c:22114
void Cudd_Srandom(long seed)
Definition: cuddInt.c:22943
static long cuddRand
Definition: cuddInt.c:22143
#define LEQR2
Definition: cuddInt.c:22120
static long shuffleSelect
Definition: cuddInt.c:22145

◆ Cudd_ReadEpsilon()

CUDD_VALUE_TYPE Cudd_ReadEpsilon ( DdManager dd)

Function********************************************************************

Synopsis [Reads the epsilon parameter of the manager.]

Description [Reads the epsilon parameter of the manager. The epsilon parameter control the comparison between floating point numbers.]

SideEffects [None]

SeeAlso [Cudd_SetEpsilon]

Definition at line 1883 of file cuddInt.c.

1885 {
1886  return(dd->epsilon);
1887 
1888 } /* end of Cudd_ReadEpsilon */
CUDD_VALUE_TYPE epsilon
Definition: cuddInt.h:390

◆ Cudd_ReadLogicZero()

DdNode* Cudd_ReadLogicZero ( DdManager dd)

Function********************************************************************

Synopsis [Returns the logic zero constant of the manager.]

Description [Returns the zero constant of the manager. The logic zero constant is the complement of the one constant, and is distinct from the arithmetic zero.]

SideEffects [None]

SeeAlso [Cudd_ReadOne Cudd_ReadZero]

Definition at line 1738 of file cuddInt.c.

1740 {
1741  return(Cudd_Not(DD_ONE(dd)));
1742 
1743 } /* end of Cudd_ReadLogicZero */
#define Cudd_Not(node)
Definition: cudd.h:343
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ Cudd_ReadMemoryInUse()

unsigned long Cudd_ReadMemoryInUse ( DdManager dd)

Function********************************************************************

Synopsis [Returns the memory in use by the manager measured in bytes.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 1925 of file cuddInt.c.

1927 {
1928  return(dd->memused);
1929 
1930 } /* end of Cudd_ReadMemoryInUse */
unsigned long memused
Definition: cuddInt.h:429

◆ Cudd_ReadNodeCount()

long Cudd_ReadNodeCount ( DdManager dd)

Function********************************************************************

Synopsis [Reports the number of nodes in BDDs and ADDs.]

Description [Reports the number of live nodes in BDDs and ADDs. This number does not include the isolated projection functions and the unused constants. These nodes that are not counted are not part of the DDs manipulated by the application.]

SideEffects [None]

SeeAlso [Cudd_ReadPeakNodeCount Cudd_zddReadNodeCount]

Definition at line 1948 of file cuddInt.c.

1950 {
1951  long count;
1952  int i;
1953 
1954 #ifndef DD_NO_DEATH_ROW
1955  cuddClearDeathRow(dd);
1956 #endif
1957 
1958  count = (long) (dd->keys - dd->dead);
1959 
1960  /* Count isolated projection functions. Their number is subtracted
1961  ** from the node count because they are not part of the BDDs.
1962  */
1963  for (i=0; i < dd->size; i++) {
1964  if (dd->vars[i]->ref == 1) count--;
1965  }
1966  /* Subtract from the count the unused constants. */
1967  if (DD_ZERO(dd)->ref == 1) count--;
1968  if (DD_PLUS_INFINITY(dd)->ref == 1) count--;
1969  if (DD_MINUS_INFINITY(dd)->ref == 1) count--;
1970 
1971  return(count);
1972 
1973 } /* end of Cudd_ReadNodeCount */
DdHalfWord ref
Definition: cudd.h:266
int size
Definition: cuddInt.h:345
#define DD_MINUS_INFINITY(dd)
Definition: cuddInt.h:908
unsigned int dead
Definition: cuddInt.h:355
unsigned int keys
Definition: cuddInt.h:353
DdNode ** vars
Definition: cuddInt.h:373
void cuddClearDeathRow(DdManager *table)
Definition: cuddInt.c:14365
#define DD_PLUS_INFINITY(dd)
Definition: cuddInt.h:894
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ Cudd_ReadOne()

DdNode* Cudd_ReadOne ( DdManager dd)

Function********************************************************************

Synopsis [Returns the one constant of the manager.]

Description [Returns the one constant of the manager. The one constant is common to ADDs and BDDs.]

SideEffects [None]

SeeAlso [Cudd_ReadZero Cudd_ReadLogicZero Cudd_ReadZddOne]

Definition at line 1716 of file cuddInt.c.

1718 {
1719  return(dd->one);
1720 
1721 } /* end of Cudd_ReadOne */
DdNode * one
Definition: cuddInt.h:329

◆ Cudd_ReadPerm()

int Cudd_ReadPerm ( DdManager dd,
int  i 
)

Function********************************************************************

Synopsis [Returns the current position of the i-th variable in the order.]

Description [Returns the current position of the i-th variable in the order. If the index is CUDD_CONST_INDEX, returns CUDD_CONST_INDEX; otherwise, if the index is out of bounds returns -1.]

SideEffects [None]

SeeAlso [Cudd_ReadInvPerm Cudd_ReadPermZdd]

Definition at line 1859 of file cuddInt.c.

1862 {
1863  if (i == CUDD_CONST_INDEX) return(CUDD_CONST_INDEX);
1864  if (i < 0 || i >= dd->size) return(-1);
1865  return(dd->perm[i]);
1866 
1867 } /* end of Cudd_ReadPerm */
int size
Definition: cuddInt.h:345
#define CUDD_CONST_INDEX
Definition: cudd.h:107
int * perm
Definition: cuddInt.h:369

◆ Cudd_ReadSize()

int Cudd_ReadSize ( DdManager dd)

Function********************************************************************

Synopsis [Returns the number of BDD variables in existance.]

Description []

SideEffects [None]

SeeAlso [Cudd_ReadZddSize]

Definition at line 1787 of file cuddInt.c.

1789 {
1790  return(dd->size);
1791 
1792 } /* end of Cudd_ReadSize */
int size
Definition: cuddInt.h:345

◆ Cudd_RecursiveDeref()

void Cudd_RecursiveDeref ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Decreases the reference count of node n.]

Description [Decreases the reference count of node n. If n dies, recursively decreases the reference counts of its children. It is used to dispose of a DD that is no longer needed.]

SideEffects [None]

SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDerefZdd]

Definition at line 14027 of file cuddInt.c.

14030 {
14031  DdNode *N;
14032  int ord;
14033  DdNodePtr *stack = table->stack;
14034  int SP = 1;
14035 
14036  unsigned int live = table->keys - table->dead;
14037  if (live > table->peakLiveNodes) {
14038  table->peakLiveNodes = live;
14039  }
14040 
14041  N = Cudd_Regular(n);
14042 
14043  do {
14044 #ifdef DD_DEBUG
14045  assert(N->ref != 0);
14046 #endif
14047 
14048  if (N->ref == 1) {
14049  N->ref = 0;
14050  table->dead++;
14051 #ifdef DD_STATS
14052  table->nodesDropped++;
14053 #endif
14054  if (cuddIsConstant(N)) {
14055  table->constants.dead++;
14056  N = stack[--SP];
14057  } else {
14058  ord = table->perm[N->index];
14059  stack[SP++] = Cudd_Regular(cuddE(N));
14060  table->subtables[ord].dead++;
14061  N = cuddT(N);
14062  }
14063  } else {
14064  cuddSatDec(N->ref);
14065  N = stack[--SP];
14066  }
14067  } while (SP != 0);
14068 
14069 } /* end of Cudd_RecursiveDeref */
DdHalfWord ref
Definition: cudd.h:266
unsigned int peakLiveNodes
Definition: cuddInt.h:445
Definition: cudd.h:264
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:373
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode ** stack
Definition: cuddInt.h:364
unsigned int dead
Definition: cuddInt.h:355
unsigned int keys
Definition: cuddInt.h:353
unsigned int dead
Definition: cuddInt.h:316
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdSubtable constants
Definition: cuddInt.h:351
int * perm
Definition: cuddInt.h:369

◆ Cudd_RecursiveDerefZdd()

void Cudd_RecursiveDerefZdd ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Decreases the reference count of ZDD node n.]

Description [Decreases the reference count of ZDD node n. If n dies, recursively decreases the reference counts of its children. It is used to dispose of a ZDD that is no longer needed.]

SideEffects [None]

SeeAlso [Cudd_Deref Cudd_Ref Cudd_RecursiveDeref]

Definition at line 14145 of file cuddInt.c.

14148 {
14149  DdNode *N;
14150  int ord;
14151  DdNodePtr *stack = table->stack;
14152  int SP = 1;
14153 
14154  N = n;
14155 
14156  do {
14157 #ifdef DD_DEBUG
14158  assert(N->ref != 0);
14159 #endif
14160 
14161  cuddSatDec(N->ref);
14162 
14163  if (N->ref == 0) {
14164  table->deadZ++;
14165 #ifdef DD_STATS
14166  table->nodesDropped++;
14167 #endif
14168 #ifdef DD_DEBUG
14169  assert(!cuddIsConstant(N));
14170 #endif
14171  ord = table->permZ[N->index];
14172  stack[SP++] = cuddE(N);
14173  table->subtableZ[ord].dead++;
14174  N = cuddT(N);
14175  } else {
14176  N = stack[--SP];
14177  }
14178  } while (SP != 0);
14179 
14180 } /* end of Cudd_RecursiveDerefZdd */
DdHalfWord ref
Definition: cudd.h:266
Definition: cudd.h:264
unsigned int deadZ
Definition: cuddInt.h:356
#define assert(ex)
Definition: util.h:141
int * permZ
Definition: cuddInt.h:370
DdNode ** stack
Definition: cuddInt.h:364
unsigned int dead
Definition: cuddInt.h:316
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ Cudd_ReduceHeap()

int Cudd_ReduceHeap ( DdManager table,
Cudd_ReorderingType  heuristic,
int  minsize 
)

AutomaticEnd Function********************************************************************

Synopsis [Main dynamic reordering routine.]

Description [Main dynamic reordering routine. Calls one of the possible reordering procedures:

  • Swapping
  • Sifting
  • Symmetric Sifting
  • Group Sifting
  • Window Permutation
  • Simulated Annealing
  • Genetic Algorithm
  • Dynamic Programming (exact)

For sifting, symmetric sifting, group sifting, and window permutation it is possible to request reordering to convergence.

The core of all methods is the reordering procedure cuddSwapInPlace() which swaps two adjacent variables and is based on Rudell's paper. Returns 1 in case of success; 0 otherwise. In the case of symmetric sifting (with and without convergence) returns 1 plus the number of symmetric variables, in case of success.]

SideEffects [Changes the variable order for all diagrams and clears the cache.]

Definition at line 14558 of file cuddInt.c.

14562 {
14563  DdHook *hook;
14564  int result;
14565  unsigned int nextDyn;
14566 #ifdef DD_STATS
14567  unsigned int initialSize;
14568  unsigned int finalSize;
14569 #endif
14570  unsigned long localTime;
14571 
14572  /* Don't reorder if there are too many dead nodes. */
14573  if (table->keys - table->dead < (unsigned) minsize)
14574  return(1);
14575 
14576  if (heuristic == CUDD_REORDER_SAME) {
14577  heuristic = table->autoMethod;
14578  }
14579  if (heuristic == CUDD_REORDER_NONE) {
14580  return(1);
14581  }
14582 
14583  /* This call to Cudd_ReduceHeap does initiate reordering. Therefore
14584  ** we count it.
14585  */
14586  table->reorderings++;
14587 
14588  localTime = util_cpu_time();
14589 
14590  /* Run the hook functions. */
14591  hook = table->preReorderingHook;
14592  while (hook != NULL) {
14593  int res = (hook->f)(table, "BDD", (void *)heuristic);
14594  if (res == 0) return(0);
14595  hook = hook->next;
14596  }
14597 
14598  if (!ddReorderPreprocess(table)) return(0);
14600 
14601  if (table->keys > table->peakLiveNodes) {
14602  table->peakLiveNodes = table->keys;
14603  }
14604 #ifdef DD_STATS
14605  initialSize = table->keys - table->isolated;
14606  ddTotalNISwaps = 0;
14607 
14608  switch(heuristic) {
14609  case CUDD_REORDER_RANDOM:
14611  (void) fprintf(table->out,"#:I_RANDOM ");
14612  break;
14613  case CUDD_REORDER_SIFT:
14619  (void) fprintf(table->out,"#:I_SIFTING ");
14620  break;
14621  case CUDD_REORDER_WINDOW2:
14622  case CUDD_REORDER_WINDOW3:
14623  case CUDD_REORDER_WINDOW4:
14627  (void) fprintf(table->out,"#:I_WINDOW ");
14628  break;
14630  (void) fprintf(table->out,"#:I_ANNEAL ");
14631  break;
14632  case CUDD_REORDER_GENETIC:
14633  (void) fprintf(table->out,"#:I_GENETIC ");
14634  break;
14635  case CUDD_REORDER_LINEAR:
14637  (void) fprintf(table->out,"#:I_LINSIFT ");
14638  break;
14639  case CUDD_REORDER_EXACT:
14640  (void) fprintf(table->out,"#:I_EXACT ");
14641  break;
14642  default:
14643  return(0);
14644  }
14645  (void) fprintf(table->out,"%8d: initial size",initialSize);
14646 #endif
14647 
14648  /* See if we should use alternate threshold for maximum growth. */
14649  if (table->reordCycle && table->reorderings % table->reordCycle == 0) {
14650  double saveGrowth = table->maxGrowth;
14651  table->maxGrowth = table->maxGrowthAlt;
14652  result = cuddTreeSifting(table,heuristic);
14653  table->maxGrowth = saveGrowth;
14654  } else {
14655  result = cuddTreeSifting(table,heuristic);
14656  }
14657 
14658 #ifdef DD_STATS
14659  (void) fprintf(table->out,"\n");
14660  finalSize = table->keys - table->isolated;
14661  (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize);
14662  (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n",
14663  ((double)(util_cpu_time() - localTime)/1000.0));
14664  (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n",
14666  (void) fprintf(table->out,"#:M_REORDER %8d: NI swaps\n",ddTotalNISwaps);
14667 #endif
14668 
14669  if (result == 0)
14670  return(0);
14671 
14672  if (!ddReorderPostprocess(table))
14673  return(0);
14674 
14675  if (table->realign) {
14676  if (!cuddZddAlignToBdd(table))
14677  return(0);
14678  }
14679 
14680  nextDyn = (table->keys - table->constants.keys + 1) *
14681  DD_DYN_RATIO + table->constants.keys;
14682  if (table->reorderings < 20 || nextDyn > table->nextDyn)
14683  table->nextDyn = nextDyn;
14684  else
14685  table->nextDyn += 20;
14686  if (table->randomizeOrder != 0) {
14687  table->nextDyn += Cudd_Random() & table->randomizeOrder;
14688  }
14689  table->reordered = 1;
14690 
14691  /* Run hook functions. */
14692  hook = table->postReorderingHook;
14693  while (hook != NULL) {
14694  int res = (hook->f)(table, "BDD", (void *)localTime);
14695  if (res == 0) return(0);
14696  hook = hook->next;
14697  }
14698  /* Update cumulative reordering time. */
14699  table->reordTime += util_cpu_time() - localTime;
14700 
14701  return(result);
14702 
14703 } /* end of Cudd_ReduceHeap */
unsigned int keys
Definition: cuddInt.h:314
unsigned long reordTime
Definition: cuddInt.h:434
Cudd_ReorderingType autoMethod
Definition: cuddInt.h:402
unsigned int peakLiveNodes
Definition: cuddInt.h:445
if(DEFINED IN_SOURCE_BUILD) set(LLVM_LINK_COMPONENTS BitWriter Core IPO IrReader InstCombine Instrumentation Target Linker Analysis ScalarOpts Support Svf Cudd) add_llvm_tool(cfl cfl.cpp) else() add_executable(cfl cfl.cpp) target_link_libraries(cfl Svf Cudd $
Definition: CMakeLists.txt:2
DdHook * preReorderingHook
Definition: cuddInt.h:421
int reordCycle
Definition: cuddInt.h:399
int cuddTreeSifting(DdManager *table, Cudd_ReorderingType method)
Definition: cuddInt.c:8507
double maxGrowthAlt
Definition: cuddInt.h:398
int realign
Definition: cuddInt.h:404
double maxGrowth
Definition: cuddInt.h:397
#define DD_DYN_RATIO
Definition: cuddInt.h:153
DD_HFP f
Definition: cuddInt.h:241
unsigned int randomizeOrder
Definition: cuddInt.h:416
int reordered
Definition: cuddInt.h:392
unsigned int nextDyn
Definition: cuddInt.h:406
unsigned int dead
Definition: cuddInt.h:355
static int ddReorderPreprocess(DdManager *table)
Definition: cuddInt.c:16147
DdHook * postReorderingHook
Definition: cuddInt.h:422
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
static int ddReorderPostprocess(DdManager *table)
Definition: cuddInt.c:16185
long util_cpu_time(void)
Definition: util.c:34
int cuddZddAlignToBdd(DdManager *table)
Definition: cuddInt.c:29753
struct DdHook * next
Definition: cuddInt.h:242
static int result
Definition: cuddInt.c:7466
unsigned int reorderings
Definition: cuddInt.h:393
DdSubtable constants
Definition: cuddInt.h:351
int isolated
Definition: cuddInt.h:368
int ddTotalNumberSwapping
Definition: cuddInt.c:14489
long Cudd_Random(void)
Definition: cuddInt.c:22881

◆ Cudd_Ref()

void Cudd_Ref ( DdNode n)

CFile***********************************************************************

FileName [cuddRef.c]

PackageName [cudd]

Synopsis [Functions that manipulate the reference counts.]

Description [External procedures included in this module:

Internal procedures included in this module:

]

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Increases the reference count of a node, if it is not saturated.]

Description []

SideEffects [None]

SeeAlso [Cudd_RecursiveDeref Cudd_Deref]

Definition at line 14002 of file cuddInt.c.

14004 {
14005 
14006  n = Cudd_Regular(n);
14007 
14008  cuddSatInc(n->ref);
14009 
14010 } /* end of Cudd_Ref */
DdHalfWord ref
Definition: cudd.h:266
#define Cudd_Regular(node)
Definition: cudd.h:373
#define cuddSatInc(x)
Definition: cuddInt.h:831

◆ Cudd_RemoveHook()

int Cudd_RemoveHook ( DdManager dd,
DD_HFP  f,
Cudd_HookType  where 
)

Function********************************************************************

Synopsis [Removes a function from a hook.]

Description [Removes a function from a hook. A hook is a list of application-provided functions called on certain occasions by the package. Returns 1 if successful; 0 the function was not in the list.]

SideEffects [None]

SeeAlso [Cudd_AddHook]

Definition at line 1991 of file cuddInt.c.

1995 {
1996  DdHook **hook, *nextHook;
1997 
1998  switch (where) {
1999  case CUDD_PRE_GC_HOOK:
2000  hook = &(dd->preGCHook);
2001  break;
2002  case CUDD_POST_GC_HOOK:
2003  hook = &(dd->postGCHook);
2004  break;
2006  hook = &(dd->preReorderingHook);
2007  break;
2009  hook = &(dd->postReorderingHook);
2010  break;
2011  default:
2012  return(0);
2013  }
2014  nextHook = *hook;
2015  while (nextHook != NULL) {
2016  if (nextHook->f == f) {
2017  *hook = nextHook->next;
2018  FREE(nextHook);
2019  return(1);
2020  }
2021  hook = &(nextHook->next);
2022  nextHook = nextHook->next;
2023  }
2024 
2025  return(0);
2026 
2027 } /* end of Cudd_RemoveHook */
#define FREE(obj)
Definition: util.h:80
DdHook * preReorderingHook
Definition: cuddInt.h:421
DD_HFP f
Definition: cuddInt.h:241
DdHook * postReorderingHook
Definition: cuddInt.h:422
struct DdHook * next
Definition: cuddInt.h:242
DdHook * postGCHook
Definition: cuddInt.h:420
DdHook * preGCHook
Definition: cuddInt.h:419

◆ Cudd_SetEpsilon()

void Cudd_SetEpsilon ( DdManager dd,
CUDD_VALUE_TYPE  ep 
)

Function********************************************************************

Synopsis [Sets the epsilon parameter of the manager to ep.]

Description [Sets the epsilon parameter of the manager to ep. The epsilon parameter control the comparison between floating point numbers.]

SideEffects [None]

SeeAlso [Cudd_ReadEpsilon]

Definition at line 1904 of file cuddInt.c.

1907 {
1908  dd->epsilon = ep;
1909 
1910 } /* end of Cudd_SetEpsilon */
CUDD_VALUE_TYPE epsilon
Definition: cuddInt.h:390

◆ Cudd_SetMinHit()

void Cudd_SetMinHit ( DdManager dd,
unsigned int  hr 
)

Function********************************************************************

Synopsis [Sets the hit rate that causes resizinig of the computed table.]

Description [Sets the minHit parameter of the manager. This parameter controls the resizing of the computed table. If the hit rate is larger than the specified value, and the cache is not already too large, then its size is doubled.]

SideEffects [None]

SeeAlso [Cudd_ReadMinHit]

Definition at line 1763 of file cuddInt.c.

1766 {
1767  /* Internally, the package manipulates the ratio of hits to
1768  ** misses instead of the ratio of hits to accesses. */
1769  dd->minHit = (double) hr / (100.0 - (double) hr);
1770 
1771 } /* end of Cudd_SetMinHit */
double minHit
Definition: cuddInt.h:341

◆ Cudd_Srandom()

void Cudd_Srandom ( long  seed)

Function********************************************************************

Synopsis [Initializer for the portable random number generator.]

Description [Initializer for the portable number generator based on ran2 in "Numerical Recipes in C." The input is the seed for the generator. If it is negative, its absolute value is taken as seed. If it is 0, then 1 is taken as seed. The initialized sets up the two recurrences used to generate a long-period stream, and sets up the shuffle table.]

SideEffects [None]

SeeAlso [Cudd_Random]

Definition at line 22943 of file cuddInt.c.

22945 {
22946 int i;
22947 
22948 if (seed < 0) cuddRand = -seed;
22949 else if (seed == 0) cuddRand = 1;
22950 else cuddRand = seed;
22952 /* Load the shuffle table (after 11 warm-ups). */
22953 for (i = 0; i < STAB_SIZE + 11; i++) {
22954 long int w;
22955 w = cuddRand / LEQQ1;
22956 cuddRand = LEQA1 * (cuddRand - w * LEQQ1) - w * LEQR1;
22957 cuddRand += (cuddRand < 0) * MODULUS1;
22959 }
22961 
22962 } /* end of Cudd_Srandom */
#define LEQQ1
Definition: cuddInt.c:22115
#define LEQR1
Definition: cuddInt.c:22116
static long shuffleTable[STAB_SIZE]
Definition: cuddInt.c:22146
#define STAB_SIZE
Definition: cuddInt.c:22121
#define MODULUS1
Definition: cuddInt.c:22113
static long cuddRand2
Definition: cuddInt.c:22144
#define LEQA1
Definition: cuddInt.c:22114
static long cuddRand
Definition: cuddInt.c:22143
static long shuffleSelect
Definition: cuddInt.c:22145

◆ Cudd_zddDiffConst()

DdNode* Cudd_zddDiffConst ( DdManager zdd,
DdNode P,
DdNode Q 
)

AutomaticEnd Function********************************************************************

Synopsis [Performs the inclusion test for ZDDs (P implies Q).]

Description [Inclusion test for ZDDs (P implies Q). No new nodes are generated by this procedure. Returns empty if true; a valid pointer different from empty or DD_NON_CONSTANT otherwise.]

SideEffects [None]

SeeAlso [Cudd_zddDiff]

Definition at line 31212 of file cuddInt.c.

31216 {
31217  int p_top, q_top;
31218  DdNode *empty = DD_ZERO(zdd), *t, *res;
31219  DdManager *table = zdd;
31220 
31221  statLine(zdd);
31222  if (P == empty)
31223  return(empty);
31224  if (Q == empty)
31225  return(P);
31226  if (P == Q)
31227  return(empty);
31228 
31229  /* Check cache. The cache is shared by cuddZddDiff(). */
31230  res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q);
31231  if (res != NULL)
31232  return(res);
31233 
31234  if (cuddIsConstant(P))
31235  p_top = P->index;
31236  else
31237  p_top = zdd->permZ[P->index];
31238  if (cuddIsConstant(Q))
31239  q_top = Q->index;
31240  else
31241  q_top = zdd->permZ[Q->index];
31242  if (p_top < q_top) {
31243  res = DD_NON_CONSTANT;
31244  } else if (p_top > q_top) {
31245  res = Cudd_zddDiffConst(zdd, P, cuddE(Q));
31246  } else {
31247  t = Cudd_zddDiffConst(zdd, cuddT(P), cuddT(Q));
31248  if (t != empty)
31249  res = DD_NON_CONSTANT;
31250  else
31251  res = Cudd_zddDiffConst(zdd, cuddE(P), cuddE(Q));
31252  }
31253 
31254  cuddCacheInsert2(table, cuddZddDiff, P, Q, res);
31255 
31256  return(res);
31257 
31258 } /* end of Cudd_zddDiffConst */
Definition: cudd.h:264
static DdNode * empty
Definition: cuddInt.c:28567
int * permZ
Definition: cuddInt.h:370
DdNode * cuddZddDiff(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddInt.c:31568
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * Cudd_zddDiffConst(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddInt.c:31212
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
#define DD_NON_CONSTANT
Definition: cuddInt.h:124
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ Cudd_zddReduceHeap()

int Cudd_zddReduceHeap ( DdManager table,
Cudd_ReorderingType  heuristic,
int  minsize 
)

AutomaticEnd Function********************************************************************

Synopsis [Main dynamic reordering routine for ZDDs.]

Description [Main dynamic reordering routine for ZDDs. Calls one of the possible reordering procedures:

  • Swapping
  • Sifting
  • Symmetric Sifting

For sifting and symmetric sifting it is possible to request reordering to convergence.

The core of all methods is the reordering procedure cuddZddSwapInPlace() which swaps two adjacent variables. Returns 1 in case of success; 0 otherwise. In the case of symmetric sifting (with and without convergence) returns 1 plus the number of symmetric variables, in case of success.]

SideEffects [Changes the variable order for all ZDDs and clears the cache.]

Definition at line 29608 of file cuddInt.c.

29612 {
29613  DdHook *hook;
29614  int result;
29615  unsigned int nextDyn;
29616 #ifdef DD_STATS
29617  unsigned int initialSize;
29618  unsigned int finalSize;
29619 #endif
29620  unsigned long localTime;
29621 
29622  /* Don't reorder if there are too many dead nodes. */
29623  if (table->keysZ - table->deadZ < (unsigned) minsize)
29624  return(1);
29625 
29626  if (heuristic == CUDD_REORDER_SAME) {
29627  heuristic = table->autoMethodZ;
29628  }
29629  if (heuristic == CUDD_REORDER_NONE) {
29630  return(1);
29631  }
29632 
29633  /* This call to Cudd_zddReduceHeap does initiate reordering. Therefore
29634  ** we count it.
29635  */
29636  table->reorderings++;
29637  empty = table->zero;
29638 
29639  localTime = util_cpu_time();
29640 
29641  /* Run the hook functions. */
29642  hook = table->preReorderingHook;
29643  while (hook != NULL) {
29644  int res = (hook->f)(table, "ZDD", (void *)heuristic);
29645  if (res == 0) return(0);
29646  hook = hook->next;
29647  }
29648 
29649  /* Clear the cache and collect garbage. */
29650  zddReorderPreprocess(table);
29652 
29653 #ifdef DD_STATS
29654  initialSize = table->keysZ;
29655 
29656  switch(heuristic) {
29657  case CUDD_REORDER_RANDOM:
29659  (void) fprintf(table->out,"#:I_RANDOM ");
29660  break;
29661  case CUDD_REORDER_SIFT:
29665  (void) fprintf(table->out,"#:I_SIFTING ");
29666  break;
29667  case CUDD_REORDER_LINEAR:
29669  (void) fprintf(table->out,"#:I_LINSIFT ");
29670  break;
29671  default:
29672  (void) fprintf(table->err,"Unsupported ZDD reordering method\n");
29673  return(0);
29674  }
29675  (void) fprintf(table->out,"%8d: initial size",initialSize);
29676 #endif
29677 
29678  result = cuddZddTreeSifting(table,heuristic);
29679 
29680 #ifdef DD_STATS
29681  (void) fprintf(table->out,"\n");
29682  finalSize = table->keysZ;
29683  (void) fprintf(table->out,"#:F_REORDER %8d: final size\n",finalSize);
29684  (void) fprintf(table->out,"#:T_REORDER %8g: total time (sec)\n",
29685  ((double)(util_cpu_time() - localTime)/1000.0));
29686  (void) fprintf(table->out,"#:N_REORDER %8d: total swaps\n",
29688 #endif
29689 
29690  if (result == 0)
29691  return(0);
29692 
29693  if (!zddReorderPostprocess(table))
29694  return(0);
29695 
29696  if (table->realignZ) {
29697  if (!cuddBddAlignToZdd(table))
29698  return(0);
29699  }
29700 
29701  nextDyn = table->keysZ * DD_DYN_RATIO;
29702  if (table->reorderings < 20 || nextDyn > table->nextDyn)
29703  table->nextDyn = nextDyn;
29704  else
29705  table->nextDyn += 20;
29706 
29707  table->reordered = 1;
29708 
29709  /* Run hook functions. */
29710  hook = table->postReorderingHook;
29711  while (hook != NULL) {
29712  int res = (hook->f)(table, "ZDD", (void *)localTime);
29713  if (res == 0) return(0);
29714  hook = hook->next;
29715  }
29716  /* Update cumulative reordering time. */
29717  table->reordTime += util_cpu_time() - localTime;
29718 
29719  return(result);
29720 
29721 } /* end of Cudd_zddReduceHeap */
int cuddBddAlignToZdd(DdManager *table)
Definition: cuddInt.c:15572
int cuddZddTreeSifting(DdManager *table, Cudd_ReorderingType method)
Definition: cuddInt.c:26558
unsigned long reordTime
Definition: cuddInt.h:434
unsigned int deadZ
Definition: cuddInt.h:356
DdHook * preReorderingHook
Definition: cuddInt.h:421
DdNode * zero
Definition: cuddInt.h:330
static DdNode * empty
Definition: cuddInt.c:28567
FILE * err
Definition: cuddInt.h:424
Cudd_ReorderingType autoMethodZ
Definition: cuddInt.h:403
#define DD_DYN_RATIO
Definition: cuddInt.h:153
static void zddReorderPreprocess(DdManager *table)
Definition: cuddInt.c:30815
DD_HFP f
Definition: cuddInt.h:241
int reordered
Definition: cuddInt.h:392
unsigned int nextDyn
Definition: cuddInt.h:406
DdHook * postReorderingHook
Definition: cuddInt.h:422
FILE * out
Definition: cuddInt.h:423
int realignZ
Definition: cuddInt.h:405
long util_cpu_time(void)
Definition: util.c:34
int zddTotalNumberSwapping
Definition: cuddInt.c:28565
struct DdHook * next
Definition: cuddInt.h:242
static int result
Definition: cuddInt.c:7466
unsigned int reorderings
Definition: cuddInt.h:393
unsigned int keysZ
Definition: cuddInt.h:354
static int zddReorderPostprocess(DdManager *table)
Definition: cuddInt.c:30844

◆ cuddAddCmplRecur()

DdNode* cuddAddCmplRecur ( DdManager dd,
DdNode f 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_addCmpl.]

Description [Performs the recursive step of Cudd_addCmpl. Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addCmpl]

Definition at line 527 of file cuddInt.c.

530 {
531  DdNode *one,*zero;
532  DdNode *r,*Fv,*Fnv,*t,*e;
533 
534  statLine(dd);
535  one = DD_ONE(dd);
536  zero = DD_ZERO(dd);
537 
538  if (cuddIsConstant(f)) {
539  if (f == zero) {
540  return(one);
541  } else {
542  return(zero);
543  }
544  }
545  r = cuddCacheLookup1(dd,Cudd_addCmpl,f);
546  if (r != NULL) {
547  return(r);
548  }
549  Fv = cuddT(f);
550  Fnv = cuddE(f);
551  t = cuddAddCmplRecur(dd,Fv);
552  if (t == NULL) return(NULL);
553  cuddRef(t);
554  e = cuddAddCmplRecur(dd,Fnv);
555  if (e == NULL) {
556  Cudd_RecursiveDeref(dd,t);
557  return(NULL);
558  }
559  cuddRef(e);
560  r = (t == e) ? t : cuddUniqueInter(dd,(int)f->index,t,e);
561  if (r == NULL) {
562  Cudd_RecursiveDeref(dd, t);
563  Cudd_RecursiveDeref(dd, e);
564  return(NULL);
565  }
566  cuddDeref(t);
567  cuddDeref(e);
569  return(r);
570 
571 } /* end of cuddAddCmplRecur */
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddInt.c:4371
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
DdNode * Cudd_addCmpl(DdManager *dd, DdNode *f)
Definition: cuddInt.c:312
DdNode * cuddCacheLookup1(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddInt.c:4591
static DdNode * one
Definition: cuddInt.c:16562
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
#define statLine(dd)
Definition: cuddInt.h:990
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddAddCmplRecur(DdManager *dd, DdNode *f)
Definition: cuddInt.c:527
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddAddIteRecur()

DdNode* cuddAddIteRecur ( DdManager dd,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Implements the recursive step of Cudd_addIte(f,g,h).]

Description [Implements the recursive step of Cudd_addIte(f,g,h). Returns a pointer to the resulting ADD if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_addIte]

Definition at line 410 of file cuddInt.c.

415 {
416  DdNode *one,*zero;
417  DdNode *r,*Fv,*Fnv,*Gv,*Gnv,*Hv,*Hnv,*t,*e;
418  unsigned int topf,topg,toph,v;
419  int index;
420 
421  statLine(dd);
422  /* Trivial cases. */
423 
424  /* One variable cases. */
425  if (f == (one = DD_ONE(dd))) { /* ITE(1,G,H) = G */
426  return(g);
427  }
428  if (f == (zero = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
429  return(h);
430  }
431 
432  /* From now on, f is known to not be a constant. */
433  addVarToConst(f,&g,&h,one,zero);
434 
435  /* Check remaining one variable cases. */
436  if (g == h) { /* ITE(F,G,G) = G */
437  return(g);
438  }
439 
440  if (g == one) { /* ITE(F,1,0) = F */
441  if (h == zero) return(f);
442  }
443 
444  topf = cuddI(dd,f->index);
445  topg = cuddI(dd,g->index);
446  toph = cuddI(dd,h->index);
447  v = ddMin(topg,toph);
448 
449  /* A shortcut: ITE(F,G,H) = (x,G,H) if F=(x,1,0), x < top(G,H). */
450  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
451  r = cuddUniqueInter(dd,(int)f->index,g,h);
452  return(r);
453  }
454  if (topf < v && cuddT(f) == zero && cuddE(f) == one) {
455  r = cuddUniqueInter(dd,(int)f->index,h,g);
456  return(r);
457  }
458 
459  /* Check cache. */
460  r = cuddCacheLookup(dd,DD_ADD_ITE_TAG,f,g,h);
461  if (r != NULL) {
462  return(r);
463  }
464 
465  /* Compute cofactors. */
466  if (topf <= v) {
467  v = ddMin(topf,v); /* v = top_var(F,G,H) */
468  index = f->index;
469  Fv = cuddT(f); Fnv = cuddE(f);
470  } else {
471  Fv = Fnv = f;
472  }
473  if (topg == v) {
474  index = g->index;
475  Gv = cuddT(g); Gnv = cuddE(g);
476  } else {
477  Gv = Gnv = g;
478  }
479  if (toph == v) {
480  index = h->index;
481  Hv = cuddT(h); Hnv = cuddE(h);
482  } else {
483  Hv = Hnv = h;
484  }
485 
486  /* Recursive step. */
487  t = cuddAddIteRecur(dd,Fv,Gv,Hv);
488  if (t == NULL) return(NULL);
489  cuddRef(t);
490 
491  e = cuddAddIteRecur(dd,Fnv,Gnv,Hnv);
492  if (e == NULL) {
493  Cudd_RecursiveDeref(dd,t);
494  return(NULL);
495  }
496  cuddRef(e);
497 
498  r = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
499  if (r == NULL) {
500  Cudd_RecursiveDeref(dd,t);
501  Cudd_RecursiveDeref(dd,e);
502  return(NULL);
503  }
504  cuddDeref(t);
505  cuddDeref(e);
506 
507  cuddCacheInsert(dd,DD_ADD_ITE_TAG,f,g,h,r);
508 
509  return(r);
510 
511 } /* end of cuddAddIteRecur */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:4413
static DdNode * one
Definition: cuddInt.c:16562
#define DD_ADD_ITE_TAG
Definition: cuddInt.h:173
static void addVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *one, DdNode *zero)
Definition: cuddInt.c:590
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
#define statLine(dd)
Definition: cuddInt.h:990
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddAddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:410
#define cuddI(dd, index)
Definition: cuddInt.h:659
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddInt.c:4283
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddAllocNode()

DdNode* cuddAllocNode ( DdManager unique)

AutomaticEnd Function********************************************************************

Synopsis [Fast storage allocation for DdNodes in the table.]

Description [Fast storage allocation for DdNodes in the table. The first 4 bytes of a chunk contain a pointer to the next block; the rest contains DD_MEM_CHUNK spaces for DdNodes. Returns a pointer to a new node if successful; NULL is memory is full.]

SideEffects [None]

SeeAlso [cuddDynamicAllocNode]

Definition at line 19624 of file cuddInt.c.

19626 {
19627 int i;
19628 DdNodePtr *mem;
19629 DdNode *list, *node;
19630 extern DD_OOMFP MMoutOfMemory;
19631 DD_OOMFP saveHandler;
19632 
19633 if (unique->nextFree == NULL) { /* free list is empty */
19634 /* Check for exceeded limits. */
19635 if ((unique->keys - unique->dead) + (unique->keysZ - unique->deadZ) >
19636 unique->maxLive) {
19637 unique->errorCode = CUDD_TOO_MANY_NODES;
19638 return(NULL);
19639 }
19640 if (util_cpu_time() - unique->startTime > unique->timeLimit) {
19642 return(NULL);
19643 }
19644 if (unique->stash == NULL || unique->memused > unique->maxmemhard) {
19645 (void) cuddGarbageCollect(unique,1);
19646 mem = NULL;
19647 }
19648 if (unique->nextFree == NULL) {
19649 if (unique->memused > unique->maxmemhard) {
19651 return(NULL);
19652 }
19653 /* Try to allocate a new block. */
19654 saveHandler = MMoutOfMemory;
19655 MMoutOfMemory = Cudd_OutOfMem;
19656 mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1);
19657 MMoutOfMemory = saveHandler;
19658 if (mem == NULL) {
19659 /* No more memory: Try collecting garbage. If this succeeds,
19660 ** we end up with mem still NULL, but unique->nextFree !=
19661 ** NULL. */
19662 if (cuddGarbageCollect(unique,1) == 0) {
19663 /* Last resort: Free the memory stashed away, if there
19664 ** any. If this succeeeds, mem != NULL and
19665 ** unique->nextFree still NULL. */
19666 if (unique->stash != NULL) {
19667 FREE(unique->stash);
19668 unique->stash = NULL;
19669 /* Inhibit resizing of tables. */
19670 cuddSlowTableGrowth(unique);
19671 /* Now try again. */
19672 mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1);
19673 }
19674 if (mem == NULL) {
19675 /* Out of luck. Call the default handler to do
19676 ** whatever it specifies for a failed malloc.
19677 ** If this handler returns, then set error code,
19678 ** print warning, and return. */
19679 (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1));
19680 unique->errorCode = CUDD_MEMORY_OUT;
19681 #ifdef DD_VERBOSE
19682 (void) fprintf(unique->err,
19683 "cuddAllocNode: out of memory");
19684 (void) fprintf(unique->err, "Memory in use = %lu\n",
19685 unique->memused);
19686 #endif
19687 return(NULL);
19688 }
19689 }
19690 }
19691 if (mem != NULL) { /* successful allocation; slice memory */
19692 ptruint offset;
19693 unique->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode);
19694 mem[0] = (DdNodePtr) unique->memoryList;
19695 unique->memoryList = mem;
19696 
19697 /* Here we rely on the fact that a DdNode is as large
19698 ** as 4 pointers. */
19699 offset = (ptruint) mem & (sizeof(DdNode) - 1);
19700 mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr);
19701 assert(((ptruint) mem & (sizeof(DdNode) - 1)) == 0);
19702 list = (DdNode *) mem;
19703 
19704 i = 1;
19705 do {
19706 list[i - 1].ref = 0;
19707 list[i - 1].next = &list[i];
19708 } while (++i < DD_MEM_CHUNK);
19709 
19710 list[DD_MEM_CHUNK-1].ref = 0;
19711 list[DD_MEM_CHUNK-1].next = NULL;
19712 
19713 unique->nextFree = &list[0];
19714 }
19715 }
19716 }
19717 unique->allocated++;
19718 node = unique->nextFree;
19719 unique->nextFree = node->next;
19720 return(node);
19721 
19722 } /* end of cuddAllocNode */
DdHalfWord ref
Definition: cudd.h:266
double allocated
Definition: cuddInt.h:365
Definition: cudd.h:264
unsigned int deadZ
Definition: cuddInt.h:356
#define FREE(obj)
Definition: util.h:80
unsigned long startTime
Definition: cuddInt.h:426
#define assert(ex)
Definition: util.h:141
FILE * err
Definition: cuddInt.h:424
DdNode * DdNodePtr
Definition: cuddInt.h:253
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddInt.c:20120
void(* DD_OOMFP)(long)
Definition: cudd.h:300
struct DdNode DdNode
Definition: cudd.h:256
unsigned int dead
Definition: cuddInt.h:355
unsigned int maxLive
Definition: cuddInt.h:357
char * stash
Definition: cuddInt.h:382
void cuddSlowTableGrowth(DdManager *unique)
Definition: cuddInt.c:21237
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
DdNode * next
Definition: cudd.h:267
long util_cpu_time(void)
Definition: util.c:34
void(* MMoutOfMemory)(long)
Definition: util.c:105
DdNode ** memoryList
Definition: cuddInt.h:380
unsigned long memused
Definition: cuddInt.h:429
unsigned int ptruint
Definition: cuddInt.h:250
DdNode * nextFree
Definition: cuddInt.h:381
unsigned long maxmemhard
Definition: cuddInt.h:431
void Cudd_OutOfMem(long size)
Definition: cuddInt.c:22982
#define DD_MEM_CHUNK
Definition: cuddInt.h:105
unsigned int keysZ
Definition: cuddInt.h:354
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddAnnealing()

int cuddAnnealing ( DdManager table,
int  lower,
int  upper 
)

AutomaticEnd Function********************************************************************

Synopsis [Get new variable-order by simulated annealing algorithm.]

Description [Get x, y by random selection. Choose either exchange or jump randomly. In case of jump, choose between jump_up and jump_down randomly. Do exchange or jump and get optimal case. Loop until there is no improvement or temperature reaches minimum. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 761 of file cuddInt.c.

765 {
766  int nvars;
767  int size;
768  int x,y;
769  int result;
770  int c1, c2, c3, c4;
771  int BestCost;
772  int *BestOrder;
773  double NewTemp, temp;
774  double rand1;
775  int innerloop, maxGen;
776  int ecount, ucount, dcount;
777 
778  nvars = upper - lower + 1;
779 
780  result = cuddSifting(table,lower,upper);
781 #ifdef DD_STATS
782  (void) fprintf(table->out,"\n");
783 #endif
784  if (result == 0) return(0);
785 
786  size = table->keys - table->isolated;
787 
788  /* Keep track of the best order. */
789  BestCost = size;
790  BestOrder = ALLOC(int,nvars);
791  if (BestOrder == NULL) {
792  table->errorCode = CUDD_MEMORY_OUT;
793  return(0);
794  }
795  copyOrder(table,BestOrder,lower,upper);
796 
797  temp = BETA * size;
798  maxGen = (int) (MAXGEN_RATIO * nvars);
799 
800  c1 = size + 10;
801  c2 = c1 + 10;
802  c3 = size;
803  c4 = c2 + 10;
804  ecount = ucount = dcount = 0;
805 
806  while (!stopping_criterion(c1, c2, c3, c4, temp)) {
807 #ifdef DD_STATS
808  (void) fprintf(table->out,"temp=%f\tsize=%d\tgen=%d\t",
809  temp,size,maxGen);
810  tosses = acceptances = 0;
811 #endif
812  for (innerloop = 0; innerloop < maxGen; innerloop++) {
813  /* Choose x, y randomly. */
814  x = (int) Cudd_Random() % nvars;
815  do {
816  y = (int) Cudd_Random() % nvars;
817  } while (x == y);
818  x += lower;
819  y += lower;
820  if (x > y) {
821  int tmp = x;
822  x = y;
823  y = tmp;
824  }
825 
826  /* Choose move with roulette wheel. */
827  rand1 = random_generator();
828  if (rand1 < EXC_PROB) {
829  result = ddExchange(table,x,y,temp); /* exchange */
830  ecount++;
831 #if 0
832  (void) fprintf(table->out,
833  "Exchange of %d and %d: size = %d\n",
834  x,y,table->keys - table->isolated);
835 #endif
836  } else if (rand1 < EXC_PROB + JUMP_UP_PROB) {
837  result = ddJumpingAux(table,y,x,y,temp); /* jumping_up */
838  ucount++;
839 #if 0
840  (void) fprintf(table->out,
841  "Jump up of %d to %d: size = %d\n",
842  y,x,table->keys - table->isolated);
843 #endif
844  } else {
845  result = ddJumpingAux(table,x,x,y,temp); /* jumping_down */
846  dcount++;
847 #if 0
848  (void) fprintf(table->out,
849  "Jump down of %d to %d: size = %d\n",
850  x,y,table->keys - table->isolated);
851 #endif
852  }
853 
854  if (!result) {
855  FREE(BestOrder);
856  return(0);
857  }
858 
859  size = table->keys - table->isolated; /* keep current size */
860  if (size < BestCost) { /* update best order */
861  BestCost = size;
862  copyOrder(table,BestOrder,lower,upper);
863  }
864  }
865  c1 = c2;
866  c2 = c3;
867  c3 = c4;
868  c4 = size;
869  NewTemp = ALPHA * temp;
870  if (NewTemp >= 1.0) {
871  maxGen = (int)(log(NewTemp) / log(temp) * maxGen);
872  }
873  temp = NewTemp; /* control variable */
874 #ifdef DD_STATS
875  (void) fprintf(table->out,"uphill = %d\taccepted = %d\n",
876  tosses,acceptances);
877  fflush(table->out);
878 #endif
879  }
880 
881  result = restoreOrder(table,BestOrder,lower,upper);
882  FREE(BestOrder);
883  if (!result) return(0);
884 #ifdef DD_STATS
885  fprintf(table->out,"#:N_EXCHANGE %8d : total exchanges\n",ecount);
886  fprintf(table->out,"#:N_JUMPUP %8d : total jumps up\n",ucount);
887  fprintf(table->out,"#:N_JUMPDOWN %8d : total jumps down",dcount);
888 #endif
889  return(1);
890 
891 } /* end of cuddAnnealing */
static void copyOrder(DdManager *table, int *array, int lower, int upper)
Definition: cuddInt.c:1365
#define FREE(obj)
Definition: util.h:80
static int ddExchange(DdManager *table, int x, int y, double temp)
Definition: cuddInt.c:962
#define ALPHA
Definition: cuddInt.c:681
static int stopping_criterion(int c1, int c2, int c3, int c4, double temp)
Definition: cuddInt.c:912
#define BETA
Definition: cuddInt.c:680
int cuddSifting(DdManager *table, int lower, int upper)
Definition: cuddInt.c:14824
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static int restoreOrder(DdManager *table, int *array, int lower, int upper)
Definition: cuddInt.c:1395
#define MAXGEN_RATIO
Definition: cuddInt.c:684
static int result
Definition: cuddInt.c:7466
static double random_generator(void)
Definition: cuddInt.c:942
static int ddJumpingAux(DdManager *table, int x, int x_low, int x_high, double temp)
Definition: cuddInt.c:1111
#define JUMP_UP_PROB
Definition: cuddInt.c:683
int isolated
Definition: cuddInt.h:368
long Cudd_Random(void)
Definition: cuddInt.c:22881
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
#define EXC_PROB
Definition: cuddInt.c:682

◆ cuddBddAlignToZdd()

int cuddBddAlignToZdd ( DdManager table)

Function********************************************************************

Synopsis [Reorders BDD variables according to the order of the ZDD variables.]

Description [Reorders BDD variables according to the order of the ZDD variables. This function can be called at the end of ZDD reordering to insure that the order of the BDD variables is consistent with the order of the ZDD variables. The number of ZDD variables must be a multiple of the number of BDD variables. Let M be the ratio of the two numbers. cuddBddAlignToZdd then considers the ZDD variables from M*i to (M+1)*i-1 as corresponding to BDD variable i. This function should be normally called from Cudd_zddReduceHeap, which clears the cache. Returns 1 in case of success; 0 otherwise.]

SideEffects [Changes the BDD variable order for all diagrams and performs garbage collection of the BDD unique table.]

SeeAlso [Cudd_ShuffleHeap Cudd_zddReduceHeap]

Definition at line 15572 of file cuddInt.c.

15574 {
15575  int *invperm; /* permutation array */
15576  int M; /* ratio of ZDD variables to BDD variables */
15577  int i; /* loop index */
15578  int result; /* return value */
15579 
15580  /* We assume that a ratio of 0 is OK. */
15581  if (table->size == 0)
15582  return(1);
15583 
15584  M = table->sizeZ / table->size;
15585  /* Check whether the number of ZDD variables is a multiple of the
15586  ** number of BDD variables.
15587  */
15588  if (M * table->size != table->sizeZ)
15589  return(0);
15590  /* Create and initialize the inverse permutation array. */
15591  invperm = ALLOC(int,table->size);
15592  if (invperm == NULL) {
15593  table->errorCode = CUDD_MEMORY_OUT;
15594  return(0);
15595  }
15596  for (i = 0; i < table->sizeZ; i += M) {
15597  int indexZ = table->invpermZ[i];
15598  int index = indexZ / M;
15599  invperm[i / M] = index;
15600  }
15601  /* Eliminate dead nodes. Do not scan the cache again, because we
15602  ** assume that Cudd_zddReduceHeap has already cleared it.
15603  */
15604  cuddGarbageCollect(table,0);
15605 
15606  /* Initialize number of isolated projection functions. */
15607  table->isolated = 0;
15608  for (i = 0; i < table->size; i++) {
15609  if (table->vars[i]->ref == 1) table->isolated++;
15610  }
15611 
15612  /* Initialize the interaction matrix. */
15613  result = cuddInitInteract(table);
15614  if (result == 0) return(0);
15615 
15616  result = ddShuffle2(table, invperm);
15617  FREE(invperm);
15618  /* Free interaction matrix. */
15619  FREE(table->interact);
15620  /* Fix the BDD variable group tree. */
15621  bddFixTree(table,table->tree);
15622  return(result);
15623 
15624 } /* end of cuddBddAlignToZdd */
DdHalfWord ref
Definition: cudd.h:266
#define FREE(obj)
Definition: util.h:80
int * invpermZ
Definition: cuddInt.h:372
int cuddInitInteract(DdManager *table)
Definition: cuddInt.c:10963
int size
Definition: cuddInt.h:345
MtrNode * tree
Definition: cuddInt.h:408
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddInt.c:20120
#define ALLOC(type, num)
Definition: util.h:76
static void bddFixTree(DdManager *table, MtrNode *treenode)
Definition: cuddInt.c:16331
long * interact
Definition: cuddInt.h:377
int sizeZ
Definition: cuddInt.h:346
static int result
Definition: cuddInt.c:7466
DdNode ** vars
Definition: cuddInt.h:373
int isolated
Definition: cuddInt.h:368
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
static int ddShuffle2(DdManager *table, int *permutation)
Definition: cuddInt.c:16218

◆ cuddBddAndRecur()

DdNode* cuddBddAndRecur ( DdManager manager,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Implements the recursive step of Cudd_bddAnd.]

Description [Implements the recursive step of Cudd_bddAnd by taking the conjunction of two BDDs. Returns a pointer to the result is successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddAnd]

Definition at line 3633 of file cuddInt.c.

3637 {
3638  DdNode *F, *fv, *fnv, *G, *gv, *gnv;
3639  DdNode *one, *r, *t, *e;
3640  unsigned int topf, topg, index;
3641 
3642  statLine(manager);
3643  one = DD_ONE(manager);
3644 
3645  /* Terminal cases. */
3646  F = Cudd_Regular(f);
3647  G = Cudd_Regular(g);
3648  if (F == G) {
3649  if (f == g) return(f);
3650  else return(Cudd_Not(one));
3651  }
3652  if (F == one) {
3653  if (f == one) return(g);
3654  else return(f);
3655  }
3656  if (G == one) {
3657  if (g == one) return(f);
3658  else return(g);
3659  }
3660 
3661  /* At this point f and g are not constant. */
3662  if (f > g) { /* Try to increase cache efficiency. */
3663  DdNode *tmp = f;
3664  f = g;
3665  g = tmp;
3666  F = Cudd_Regular(f);
3667  G = Cudd_Regular(g);
3668  }
3669 
3670  /* Check cache. */
3671  if (F->ref != 1 || G->ref != 1) {
3672  r = cuddCacheLookup2(manager, Cudd_bddAnd, f, g);
3673  if (r != NULL) return(r);
3674  }
3675 
3676  /* Here we can skip the use of cuddI, because the operands are known
3677  ** to be non-constant.
3678  */
3679  topf = manager->perm[F->index];
3680  topg = manager->perm[G->index];
3681 
3682  /* Compute cofactors. */
3683  if (topf <= topg) {
3684  index = F->index;
3685  fv = cuddT(F);
3686  fnv = cuddE(F);
3687  if (Cudd_IsComplement(f)) {
3688  fv = Cudd_Not(fv);
3689  fnv = Cudd_Not(fnv);
3690  }
3691  } else {
3692  index = G->index;
3693  fv = fnv = f;
3694  }
3695 
3696  if (topg <= topf) {
3697  gv = cuddT(G);
3698  gnv = cuddE(G);
3699  if (Cudd_IsComplement(g)) {
3700  gv = Cudd_Not(gv);
3701  gnv = Cudd_Not(gnv);
3702  }
3703  } else {
3704  gv = gnv = g;
3705  }
3706 
3707  t = cuddBddAndRecur(manager, fv, gv);
3708  if (t == NULL) return(NULL);
3709  cuddRef(t);
3710 
3711  e = cuddBddAndRecur(manager, fnv, gnv);
3712  if (e == NULL) {
3713  Cudd_IterDerefBdd(manager, t);
3714  return(NULL);
3715  }
3716  cuddRef(e);
3717 
3718  if (t == e) {
3719  r = t;
3720  } else {
3721  if (Cudd_IsComplement(t)) {
3722  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
3723  if (r == NULL) {
3724  Cudd_IterDerefBdd(manager, t);
3725  Cudd_IterDerefBdd(manager, e);
3726  return(NULL);
3727  }
3728  r = Cudd_Not(r);
3729  } else {
3730  r = cuddUniqueInter(manager,(int)index,t,e);
3731  if (r == NULL) {
3732  Cudd_IterDerefBdd(manager, t);
3733  Cudd_IterDerefBdd(manager, e);
3734  return(NULL);
3735  }
3736  }
3737  }
3738  cuddDeref(e);
3739  cuddDeref(t);
3740  if (F->ref != 1 || G->ref != 1)
3741  cuddCacheInsert2(manager, Cudd_bddAnd, f, g, r);
3742  return(r);
3743 
3744 } /* end of cuddBddAndRecur */
DdHalfWord ref
Definition: cudd.h:266
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3114
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14090
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633
int * perm
Definition: cuddInt.h:369
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329

◆ cuddBddBooleanDiffRecur()

DdNode* cuddBddBooleanDiffRecur ( DdManager manager,
DdNode f,
DdNode var 
)

Function********************************************************************

Synopsis [Performs the recursive steps of Cudd_bddBoleanDiff.]

Description [Performs the recursive steps of Cudd_bddBoleanDiff. Returns the BDD obtained by XORing the cofactors of f with respect to var if successful; NULL otherwise. Exploits the fact that dF/dx = dF'/dx.]

SideEffects [None]

SeeAlso []

Definition at line 2719 of file cuddInt.c.

2723 {
2724  DdNode *T, *E, *res, *res1, *res2;
2725 
2726  statLine(manager);
2727  if (cuddI(manager,f->index) > manager->perm[var->index]) {
2728  /* f does not depend on var. */
2729  return(Cudd_Not(DD_ONE(manager)));
2730  }
2731 
2732  /* From now on, f is non-constant. */
2733 
2734  /* If the two indices are the same, so are their levels. */
2735  if (f->index == var->index) {
2736  res = cuddBddXorRecur(manager, cuddT(f), cuddE(f));
2737  return(res);
2738  }
2739 
2740  /* From now on, cuddI(manager,f->index) < cuddI(manager,cube->index). */
2741 
2742  /* Check the cache. */
2743  res = cuddCacheLookup2(manager, cuddBddBooleanDiffRecur, f, var);
2744  if (res != NULL) {
2745  return(res);
2746  }
2747 
2748  /* Compute the cofactors of f. */
2749  T = cuddT(f); E = cuddE(f);
2750 
2751  res1 = cuddBddBooleanDiffRecur(manager, T, var);
2752  if (res1 == NULL) return(NULL);
2753  cuddRef(res1);
2754  res2 = cuddBddBooleanDiffRecur(manager, Cudd_Regular(E), var);
2755  if (res2 == NULL) {
2756  Cudd_IterDerefBdd(manager, res1);
2757  return(NULL);
2758  }
2759  cuddRef(res2);
2760  /* ITE takes care of possible complementation of res1 and of the
2761  ** case in which res1 == res2. */
2762  res = cuddBddIteRecur(manager, manager->vars[f->index], res1, res2);
2763  if (res == NULL) {
2764  Cudd_IterDerefBdd(manager, res1);
2765  Cudd_IterDerefBdd(manager, res2);
2766  return(NULL);
2767  }
2768  cuddDeref(res1);
2769  cuddDeref(res2);
2770  cuddCacheInsert2(manager, cuddBddBooleanDiffRecur, f, var, res);
2771  return(res);
2772 
2773 } /* end of cuddBddBooleanDiffRecur */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_Regular(node)
Definition: cudd.h:373
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:3380
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14090
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
DdHalfWord index
Definition: cudd.h:265
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
DdNode * cuddBddBooleanDiffRecur(DdManager *manager, DdNode *f, DdNode *var)
Definition: cuddInt.c:2719
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3761
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329

◆ cuddBddExistAbstractRecur()

DdNode* cuddBddExistAbstractRecur ( DdManager manager,
DdNode f,
DdNode cube 
)

Function********************************************************************

Synopsis [Performs the recursive steps of Cudd_bddExistAbstract.]

Description [Performs the recursive steps of Cudd_bddExistAbstract. Returns the BDD obtained by abstracting the variables of cube from f if successful; NULL otherwise. It is also used by Cudd_bddUnivAbstract.]

SideEffects [None]

SeeAlso [Cudd_bddExistAbstract Cudd_bddUnivAbstract]

Definition at line 2437 of file cuddInt.c.

2441 {
2442  DdNode *F, *T, *E, *res, *res1, *res2, *one;
2443 
2444  statLine(manager);
2445  one = DD_ONE(manager);
2446  F = Cudd_Regular(f);
2447 
2448  /* Cube is guaranteed to be a cube at this point. */
2449  if (cube == one || F == one) {
2450  return(f);
2451  }
2452  /* From now on, f and cube are non-constant. */
2453 
2454  /* Abstract a variable that does not appear in f. */
2455  while (manager->perm[F->index] > manager->perm[cube->index]) {
2456  cube = cuddT(cube);
2457  if (cube == one) return(f);
2458  }
2459 
2460  /* Check the cache. */
2461  if (F->ref != 1 && (res = cuddCacheLookup2(manager, Cudd_bddExistAbstract, f, cube)) != NULL) {
2462  return(res);
2463  }
2464 
2465  /* Compute the cofactors of f. */
2466  T = cuddT(F); E = cuddE(F);
2467  if (f != F) {
2468  T = Cudd_Not(T); E = Cudd_Not(E);
2469  }
2470 
2471  /* If the two indices are the same, so are their levels. */
2472  if (F->index == cube->index) {
2473  if (T == one || E == one || T == Cudd_Not(E)) {
2474  return(one);
2475  }
2476  res1 = cuddBddExistAbstractRecur(manager, T, cuddT(cube));
2477  if (res1 == NULL) return(NULL);
2478  if (res1 == one) {
2479  if (F->ref != 1)
2480  cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, one);
2481  return(one);
2482  }
2483  cuddRef(res1);
2484  res2 = cuddBddExistAbstractRecur(manager, E, cuddT(cube));
2485  if (res2 == NULL) {
2486  Cudd_IterDerefBdd(manager,res1);
2487  return(NULL);
2488  }
2489  cuddRef(res2);
2490  res = cuddBddAndRecur(manager, Cudd_Not(res1), Cudd_Not(res2));
2491  if (res == NULL) {
2492  Cudd_IterDerefBdd(manager, res1);
2493  Cudd_IterDerefBdd(manager, res2);
2494  return(NULL);
2495  }
2496  res = Cudd_Not(res);
2497  cuddRef(res);
2498  Cudd_IterDerefBdd(manager, res1);
2499  Cudd_IterDerefBdd(manager, res2);
2500  if (F->ref != 1)
2501  cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res);
2502  cuddDeref(res);
2503  return(res);
2504  } else { /* if (cuddI(manager,F->index) < cuddI(manager,cube->index)) */
2505  res1 = cuddBddExistAbstractRecur(manager, T, cube);
2506  if (res1 == NULL) return(NULL);
2507  cuddRef(res1);
2508  res2 = cuddBddExistAbstractRecur(manager, E, cube);
2509  if (res2 == NULL) {
2510  Cudd_IterDerefBdd(manager, res1);
2511  return(NULL);
2512  }
2513  cuddRef(res2);
2514  /* ITE takes care of possible complementation of res1 and of the
2515  ** case in which res1 == res2. */
2516  res = cuddBddIteRecur(manager, manager->vars[F->index], res1, res2);
2517  if (res == NULL) {
2518  Cudd_IterDerefBdd(manager, res1);
2519  Cudd_IterDerefBdd(manager, res2);
2520  return(NULL);
2521  }
2522  cuddDeref(res1);
2523  cuddDeref(res2);
2524  if (F->ref != 1)
2525  cuddCacheInsert2(manager, Cudd_bddExistAbstract, f, cube, res);
2526  return(res);
2527  }
2528 
2529 } /* end of cuddBddExistAbstractRecur */
DdHalfWord ref
Definition: cudd.h:266
#define cuddRef(n)
Definition: cuddInt.h:557
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddInt.c:2437
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:3380
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14090
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * Cudd_bddExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddInt.c:2331
DdHalfWord index
Definition: cudd.h:265
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633
int * perm
Definition: cuddInt.h:369
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329

◆ cuddBddIntersectRecur()

DdNode* cuddBddIntersectRecur ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Implements the recursive step of Cudd_bddIntersect.]

Description []

SideEffects [None]

SeeAlso [Cudd_bddIntersect]

Definition at line 3518 of file cuddInt.c.

3522 {
3523  DdNode *res;
3524  DdNode *F, *G, *t, *e;
3525  DdNode *fv, *fnv, *gv, *gnv;
3526  DdNode *one, *zero;
3527  unsigned int index, topf, topg;
3528 
3529  statLine(dd);
3530  one = DD_ONE(dd);
3531  zero = Cudd_Not(one);
3532 
3533  /* Terminal cases. */
3534  if (f == zero || g == zero || f == Cudd_Not(g)) return(zero);
3535  if (f == g || g == one) return(f);
3536  if (f == one) return(g);
3537 
3538  /* At this point f and g are not constant. */
3539  if (f > g) { DdNode *tmp = f; f = g; g = tmp; }
3540  res = cuddCacheLookup2(dd,Cudd_bddIntersect,f,g);
3541  if (res != NULL) return(res);
3542 
3543  /* Find splitting variable. Here we can skip the use of cuddI,
3544  ** because the operands are known to be non-constant.
3545  */
3546  F = Cudd_Regular(f);
3547  topf = dd->perm[F->index];
3548  G = Cudd_Regular(g);
3549  topg = dd->perm[G->index];
3550 
3551  /* Compute cofactors. */
3552  if (topf <= topg) {
3553  index = F->index;
3554  fv = cuddT(F);
3555  fnv = cuddE(F);
3556  if (Cudd_IsComplement(f)) {
3557  fv = Cudd_Not(fv);
3558  fnv = Cudd_Not(fnv);
3559  }
3560  } else {
3561  index = G->index;
3562  fv = fnv = f;
3563  }
3564 
3565  if (topg <= topf) {
3566  gv = cuddT(G);
3567  gnv = cuddE(G);
3568  if (Cudd_IsComplement(g)) {
3569  gv = Cudd_Not(gv);
3570  gnv = Cudd_Not(gnv);
3571  }
3572  } else {
3573  gv = gnv = g;
3574  }
3575 
3576  /* Compute partial results. */
3577  t = cuddBddIntersectRecur(dd,fv,gv);
3578  if (t == NULL) return(NULL);
3579  cuddRef(t);
3580  if (t != zero) {
3581  e = zero;
3582  } else {
3583  e = cuddBddIntersectRecur(dd,fnv,gnv);
3584  if (e == NULL) {
3585  Cudd_IterDerefBdd(dd, t);
3586  return(NULL);
3587  }
3588  }
3589  cuddRef(e);
3590 
3591  if (t == e) { /* both equal zero */
3592  res = t;
3593  } else if (Cudd_IsComplement(t)) {
3594  res = cuddUniqueInter(dd,(int)index,Cudd_Not(t),Cudd_Not(e));
3595  if (res == NULL) {
3596  Cudd_IterDerefBdd(dd, t);
3597  Cudd_IterDerefBdd(dd, e);
3598  return(NULL);
3599  }
3600  res = Cudd_Not(res);
3601  } else {
3602  res = cuddUniqueInter(dd,(int)index,t,e);
3603  if (res == NULL) {
3604  Cudd_IterDerefBdd(dd, t);
3605  Cudd_IterDerefBdd(dd, e);
3606  return(NULL);
3607  }
3608  }
3609  cuddDeref(e);
3610  cuddDeref(t);
3611 
3612  cuddCacheInsert2(dd,Cudd_bddIntersect,f,g,res);
3613 
3614  return(res);
3615 
3616 } /* end of cuddBddIntersectRecur */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14090
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddBddIntersectRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3518
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
DdNode * Cudd_bddIntersect(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3082

◆ cuddBddIsop()

DdNode* cuddBddIsop ( DdManager dd,
DdNode L,
DdNode U 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_bddIsop.]

Description []

SideEffects [None]

SeeAlso [Cudd_bddIsop]

Definition at line 28135 of file cuddInt.c.

28139 {
28140  DdNode *one = DD_ONE(dd);
28141  DdNode *zero = Cudd_Not(one);
28142  int v, top_l, top_u;
28143  DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud;
28144  DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1;
28145  DdNode *Isub0, *Isub1, *Id;
28146  DdNode *x;
28147  DdNode *term0, *term1, *sum;
28148  DdNode *Lv, *Uv, *Lnv, *Unv;
28149  DdNode *r;
28150  int index;
28151 
28152  statLine(dd);
28153  if (L == zero)
28154  return(zero);
28155  if (U == one)
28156  return(one);
28157 
28158  /* Check cache */
28159  r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
28160  if (r)
28161  return(r);
28162 
28163  top_l = dd->perm[Cudd_Regular(L)->index];
28164  top_u = dd->perm[Cudd_Regular(U)->index];
28165  v = ddMin(top_l, top_u);
28166 
28167  /* Compute cofactors */
28168  if (top_l == v) {
28169  index = Cudd_Regular(L)->index;
28170  Lv = Cudd_T(L);
28171  Lnv = Cudd_E(L);
28172  if (Cudd_IsComplement(L)) {
28173  Lv = Cudd_Not(Lv);
28174  Lnv = Cudd_Not(Lnv);
28175  }
28176  }
28177  else {
28178  index = Cudd_Regular(U)->index;
28179  Lv = Lnv = L;
28180  }
28181 
28182  if (top_u == v) {
28183  Uv = Cudd_T(U);
28184  Unv = Cudd_E(U);
28185  if (Cudd_IsComplement(U)) {
28186  Uv = Cudd_Not(Uv);
28187  Unv = Cudd_Not(Unv);
28188  }
28189  }
28190  else {
28191  Uv = Unv = U;
28192  }
28193 
28194  Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
28195  if (Lsub0 == NULL)
28196  return(NULL);
28197  Cudd_Ref(Lsub0);
28198  Usub0 = Unv;
28199  Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv));
28200  if (Lsub1 == NULL) {
28201  Cudd_RecursiveDeref(dd, Lsub0);
28202  return(NULL);
28203  }
28204  Cudd_Ref(Lsub1);
28205  Usub1 = Uv;
28206 
28207  Isub0 = cuddBddIsop(dd, Lsub0, Usub0);
28208  if (Isub0 == NULL) {
28209  Cudd_RecursiveDeref(dd, Lsub0);
28210  Cudd_RecursiveDeref(dd, Lsub1);
28211  return(NULL);
28212  }
28213  Cudd_Ref(Isub0);
28214  Isub1 = cuddBddIsop(dd, Lsub1, Usub1);
28215  if (Isub1 == NULL) {
28216  Cudd_RecursiveDeref(dd, Lsub0);
28217  Cudd_RecursiveDeref(dd, Lsub1);
28218  Cudd_RecursiveDeref(dd, Isub0);
28219  return(NULL);
28220  }
28221  Cudd_Ref(Isub1);
28222  Cudd_RecursiveDeref(dd, Lsub0);
28223  Cudd_RecursiveDeref(dd, Lsub1);
28224 
28225  Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0));
28226  if (Lsuper0 == NULL) {
28227  Cudd_RecursiveDeref(dd, Isub0);
28228  Cudd_RecursiveDeref(dd, Isub1);
28229  return(NULL);
28230  }
28231  Cudd_Ref(Lsuper0);
28232  Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1));
28233  if (Lsuper1 == NULL) {
28234  Cudd_RecursiveDeref(dd, Isub0);
28235  Cudd_RecursiveDeref(dd, Isub1);
28236  Cudd_RecursiveDeref(dd, Lsuper0);
28237  return(NULL);
28238  }
28239  Cudd_Ref(Lsuper1);
28240  Usuper0 = Unv;
28241  Usuper1 = Uv;
28242 
28243  /* Ld = Lsuper0 + Lsuper1 */
28244  Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1));
28245  Ld = Cudd_NotCond(Ld, Ld != NULL);
28246  if (Ld == NULL) {
28247  Cudd_RecursiveDeref(dd, Isub0);
28248  Cudd_RecursiveDeref(dd, Isub1);
28249  Cudd_RecursiveDeref(dd, Lsuper0);
28250  Cudd_RecursiveDeref(dd, Lsuper1);
28251  return(NULL);
28252  }
28253  Cudd_Ref(Ld);
28254  Ud = cuddBddAndRecur(dd, Usuper0, Usuper1);
28255  if (Ud == NULL) {
28256  Cudd_RecursiveDeref(dd, Isub0);
28257  Cudd_RecursiveDeref(dd, Isub1);
28258  Cudd_RecursiveDeref(dd, Lsuper0);
28259  Cudd_RecursiveDeref(dd, Lsuper1);
28260  Cudd_RecursiveDeref(dd, Ld);
28261  return(NULL);
28262  }
28263  Cudd_Ref(Ud);
28264  Cudd_RecursiveDeref(dd, Lsuper0);
28265  Cudd_RecursiveDeref(dd, Lsuper1);
28266 
28267  Id = cuddBddIsop(dd, Ld, Ud);
28268  if (Id == NULL) {
28269  Cudd_RecursiveDeref(dd, Isub0);
28270  Cudd_RecursiveDeref(dd, Isub1);
28271  Cudd_RecursiveDeref(dd, Ld);
28272  Cudd_RecursiveDeref(dd, Ud);
28273  return(NULL);
28274  }
28275  Cudd_Ref(Id);
28276  Cudd_RecursiveDeref(dd, Ld);
28277  Cudd_RecursiveDeref(dd, Ud);
28278 
28279  x = cuddUniqueInter(dd, index, one, zero);
28280  if (x == NULL) {
28281  Cudd_RecursiveDeref(dd, Isub0);
28282  Cudd_RecursiveDeref(dd, Isub1);
28283  Cudd_RecursiveDeref(dd, Id);
28284  return(NULL);
28285  }
28286  Cudd_Ref(x);
28287  term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0);
28288  if (term0 == NULL) {
28289  Cudd_RecursiveDeref(dd, Isub0);
28290  Cudd_RecursiveDeref(dd, Isub1);
28291  Cudd_RecursiveDeref(dd, Id);
28292  Cudd_RecursiveDeref(dd, x);
28293  return(NULL);
28294  }
28295  Cudd_Ref(term0);
28296  Cudd_RecursiveDeref(dd, Isub0);
28297  term1 = cuddBddAndRecur(dd, x, Isub1);
28298  if (term1 == NULL) {
28299  Cudd_RecursiveDeref(dd, Isub1);
28300  Cudd_RecursiveDeref(dd, Id);
28301  Cudd_RecursiveDeref(dd, x);
28302  Cudd_RecursiveDeref(dd, term0);
28303  return(NULL);
28304  }
28305  Cudd_Ref(term1);
28306  Cudd_RecursiveDeref(dd, x);
28307  Cudd_RecursiveDeref(dd, Isub1);
28308  /* sum = term0 + term1 */
28309  sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1));
28310  sum = Cudd_NotCond(sum, sum != NULL);
28311  if (sum == NULL) {
28312  Cudd_RecursiveDeref(dd, Id);
28313  Cudd_RecursiveDeref(dd, term0);
28314  Cudd_RecursiveDeref(dd, term1);
28315  return(NULL);
28316  }
28317  Cudd_Ref(sum);
28318  Cudd_RecursiveDeref(dd, term0);
28319  Cudd_RecursiveDeref(dd, term1);
28320  /* r = sum + Id */
28321  r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id));
28322  r = Cudd_NotCond(r, r != NULL);
28323  if (r == NULL) {
28324  Cudd_RecursiveDeref(dd, Id);
28325  Cudd_RecursiveDeref(dd, sum);
28326  return(NULL);
28327  }
28328  Cudd_Ref(r);
28329  Cudd_RecursiveDeref(dd, sum);
28330  Cudd_RecursiveDeref(dd, Id);
28331 
28332  cuddCacheInsert2(dd, cuddBddIsop, L, U, r);
28333 
28334  Cudd_Deref(r);
28335  return(r);
28336 
28337 } /* end of cuddBddIsop */
#define Cudd_T(node)
Definition: cudd.h:416
#define Cudd_E(node)
Definition: cudd.h:431
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
DdNode * cuddBddIsop(DdManager *dd, DdNode *L, DdNode *U)
Definition: cuddInt.c:28135
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
void Cudd_Ref(DdNode *n)
Definition: cuddInt.c:14002
#define ddMin(x, y)
Definition: cuddInt.h:771
#define Cudd_NotCond(node, c)
Definition: cudd.h:359
void Cudd_Deref(DdNode *node)
Definition: cuddInt.c:14198
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633
int * perm
Definition: cuddInt.h:369
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329

◆ cuddBddIteRecur()

DdNode* cuddBddIteRecur ( DdManager dd,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Implements the recursive step of Cudd_bddIte.]

Description [Implements the recursive step of Cudd_bddIte. Returns a pointer to the resulting BDD. NULL if the intermediate result blows up or if reordering occurs.]

SideEffects [None]

SeeAlso []

Definition at line 3380 of file cuddInt.c.

3385 {
3386  DdNode *one, *zero, *res;
3387  DdNode *r, *Fv, *Fnv, *Gv, *Gnv, *H, *Hv, *Hnv, *t, *e;
3388  unsigned int topf, topg, toph, v;
3389  int index;
3390  int comple;
3391 
3392  statLine(dd);
3393  /* Terminal cases. */
3394 
3395  /* One variable cases. */
3396  if (f == (one = DD_ONE(dd))) /* ITE(1,G,H) = G */
3397  return(g);
3398 
3399  if (f == (zero = Cudd_Not(one))) /* ITE(0,G,H) = H */
3400  return(h);
3401 
3402  /* From now on, f is known not to be a constant. */
3403  if (g == one || f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
3404  if (h == zero) { /* ITE(F,1,0) = F */
3405  return(f);
3406  } else {
3407  res = cuddBddAndRecur(dd,Cudd_Not(f),Cudd_Not(h));
3408  return(Cudd_NotCond(res,res != NULL));
3409  }
3410  } else if (g == zero || f == Cudd_Not(g)) { /* ITE(F,!F,H) = ITE(F,0,H) = !F * H */
3411  if (h == one) { /* ITE(F,0,1) = !F */
3412  return(Cudd_Not(f));
3413  } else {
3414  res = cuddBddAndRecur(dd,Cudd_Not(f),h);
3415  return(res);
3416  }
3417  }
3418  if (h == zero || f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
3419  res = cuddBddAndRecur(dd,f,g);
3420  return(res);
3421  } else if (h == one || f == Cudd_Not(h)) { /* ITE(F,G,!F) = ITE(F,G,1) = !F + G */
3422  res = cuddBddAndRecur(dd,f,Cudd_Not(g));
3423  return(Cudd_NotCond(res,res != NULL));
3424  }
3425 
3426  /* Check remaining one variable case. */
3427  if (g == h) { /* ITE(F,G,G) = G */
3428  return(g);
3429  } else if (g == Cudd_Not(h)) { /* ITE(F,G,!G) = F <-> G */
3430  res = cuddBddXorRecur(dd,f,h);
3431  return(res);
3432  }
3433 
3434  /* From here, there are no constants. */
3435  comple = bddVarToCanonicalSimple(dd, &f, &g, &h, &topf, &topg, &toph);
3436 
3437  /* f & g are now regular pointers */
3438 
3439  v = ddMin(topg, toph);
3440 
3441  /* A shortcut: ITE(F,G,H) = (v,G,H) if F = (v,1,0), v < top(G,H). */
3442  if (topf < v && cuddT(f) == one && cuddE(f) == zero) {
3443  r = cuddUniqueInter(dd, (int) f->index, g, h);
3444  return(Cudd_NotCond(r,comple && r != NULL));
3445  }
3446 
3447  /* Check cache. */
3448  r = cuddCacheLookup(dd, DD_BDD_ITE_TAG, f, g, h);
3449  if (r != NULL) {
3450  return(Cudd_NotCond(r,comple));
3451  }
3452 
3453  /* Compute cofactors. */
3454  if (topf <= v) {
3455  v = ddMin(topf, v); /* v = top_var(F,G,H) */
3456  index = f->index;
3457  Fv = cuddT(f); Fnv = cuddE(f);
3458  } else {
3459  Fv = Fnv = f;
3460  }
3461  if (topg == v) {
3462  index = g->index;
3463  Gv = cuddT(g); Gnv = cuddE(g);
3464  } else {
3465  Gv = Gnv = g;
3466  }
3467  if (toph == v) {
3468  H = Cudd_Regular(h);
3469  index = H->index;
3470  Hv = cuddT(H); Hnv = cuddE(H);
3471  if (Cudd_IsComplement(h)) {
3472  Hv = Cudd_Not(Hv);
3473  Hnv = Cudd_Not(Hnv);
3474  }
3475  } else {
3476  Hv = Hnv = h;
3477  }
3478 
3479  /* Recursive step. */
3480  t = cuddBddIteRecur(dd,Fv,Gv,Hv);
3481  if (t == NULL) return(NULL);
3482  cuddRef(t);
3483 
3484  e = cuddBddIteRecur(dd,Fnv,Gnv,Hnv);
3485  if (e == NULL) {
3486  Cudd_IterDerefBdd(dd,t);
3487  return(NULL);
3488  }
3489  cuddRef(e);
3490 
3491  r = (t == e) ? t : cuddUniqueInter(dd,index,t,e);
3492  if (r == NULL) {
3493  Cudd_IterDerefBdd(dd,t);
3494  Cudd_IterDerefBdd(dd,e);
3495  return(NULL);
3496  }
3497  cuddDeref(t);
3498  cuddDeref(e);
3499 
3500  cuddCacheInsert(dd, DD_BDD_ITE_TAG, f, g, h, r);
3501  return(Cudd_NotCond(r,comple));
3502 
3503 } /* end of cuddBddIteRecur */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:4413
static DdNode * one
Definition: cuddInt.c:16562
static int bddVarToCanonicalSimple(DdManager *dd, DdNode **fp, DdNode **gp, DdNode **hp, unsigned int *topfp, unsigned int *topgp, unsigned int *tophp)
Definition: cuddInt.c:4019
#define Cudd_Regular(node)
Definition: cudd.h:373
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:3380
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14090
#define ddMin(x, y)
Definition: cuddInt.h:771
#define DD_BDD_ITE_TAG
Definition: cuddInt.h:176
#define cuddT(node)
Definition: cuddInt.h:609
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddInt.c:4283
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:359
static DdNode * zero
Definition: cuddInt.c:16562
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3761
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633

◆ cuddBddMakePrime()

DdNode* cuddBddMakePrime ( DdManager dd,
DdNode cube,
DdNode f 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_bddMakePrime.]

Description [Performs the recursive step of Cudd_bddMakePrime. Returns the prime if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 17148 of file cuddInt.c.

17152  {
17153  DdNode *scan;
17154  DdNode *t, *e;
17155  DdNode *res = cube;
17156  DdNode *zero = Cudd_Not(DD_ONE(dd));
17157 
17158  Cudd_Ref(res);
17159  scan = cube;
17160  while (!Cudd_IsConstant(scan)) {
17161  DdNode *reg = Cudd_Regular(scan);
17162  DdNode *var = dd->vars[reg->index];
17163  DdNode *expanded = Cudd_bddExistAbstract(dd,res,var);
17164  if (expanded == NULL) {
17165  Cudd_RecursiveDeref(dd,res);
17166  return(NULL);
17167  }
17168  Cudd_Ref(expanded);
17169  if (Cudd_bddLeq(dd,expanded,f)) {
17170  Cudd_RecursiveDeref(dd,res);
17171  res = expanded;
17172  } else {
17173  Cudd_RecursiveDeref(dd,expanded);
17174  }
17175  cuddGetBranches(scan,&t,&e);
17176  if (t == zero) {
17177  scan = e;
17178  } else if (e == zero) {
17179  scan = t;
17180  } else {
17181  Cudd_RecursiveDeref(dd,res);
17182  return(NULL); /* cube is not a cube */
17183  }
17184  }
17185 
17186  if (scan == DD_ONE(dd)) {
17187  Cudd_Deref(res);
17188  return(res);
17189  } else {
17190  Cudd_RecursiveDeref(dd,res);
17191  return(NULL);
17192  }
17193 
17194  } /* end of cuddBddMakePrime */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_IsConstant(node)
Definition: cudd.h:328
#define Cudd_Regular(node)
Definition: cudd.h:373
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
void Cudd_Ref(DdNode *n)
Definition: cuddInt.c:14002
void cuddGetBranches(DdNode *g, DdNode **g1, DdNode **g0)
Definition: cuddInt.c:6196
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3283
DdNode * Cudd_bddExistAbstract(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddInt.c:2331
DdHalfWord index
Definition: cudd.h:265
DdNode ** vars
Definition: cuddInt.h:373
void Cudd_Deref(DdNode *node)
Definition: cuddInt.c:14198
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ cuddBddXorExistAbstractRecur()

DdNode* cuddBddXorExistAbstractRecur ( DdManager manager,
DdNode f,
DdNode g,
DdNode cube 
)

Function********************************************************************

Synopsis [Takes the exclusive OR of two BDDs and simultaneously abstracts the variables in cube.]

Description [Takes the exclusive OR of two BDDs and simultaneously abstracts the variables in cube. The variables are existentially abstracted. Returns a pointer to the result is successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddAndAbstract]

Definition at line 2547 of file cuddInt.c.

2552 {
2553  DdNode *F, *fv, *fnv, *G, *gv, *gnv;
2554  DdNode *one, *zero, *r, *t, *e, *Cube;
2555  unsigned int topf, topg, topcube, top, index;
2556 
2557  statLine(manager);
2558  one = DD_ONE(manager);
2559  zero = Cudd_Not(one);
2560 
2561  /* Terminal cases. */
2562  if (f == g) {
2563  return(zero);
2564  }
2565  if (f == Cudd_Not(g)) {
2566  return(one);
2567  }
2568  if (cube == one) {
2569  return(cuddBddXorRecur(manager, f, g));
2570  }
2571  if (f == one) {
2572  return(cuddBddExistAbstractRecur(manager, Cudd_Not(g), cube));
2573  }
2574  if (g == one) {
2575  return(cuddBddExistAbstractRecur(manager, Cudd_Not(f), cube));
2576  }
2577  if (f == zero) {
2578  return(cuddBddExistAbstractRecur(manager, g, cube));
2579  }
2580  if (g == zero) {
2581  return(cuddBddExistAbstractRecur(manager, f, cube));
2582  }
2583 
2584  /* At this point f, g, and cube are not constant. */
2585 
2586  if (f > g) { /* Try to increase cache efficiency. */
2587  DdNode *tmp = f;
2588  f = g;
2589  g = tmp;
2590  }
2591 
2592  /* Check cache. */
2593  r = cuddCacheLookup(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube);
2594  if (r != NULL) {
2595  return(r);
2596  }
2597 
2598  /* Here we can skip the use of cuddI, because the operands are known
2599  ** to be non-constant.
2600  */
2601  F = Cudd_Regular(f);
2602  topf = manager->perm[F->index];
2603  G = Cudd_Regular(g);
2604  topg = manager->perm[G->index];
2605  top = ddMin(topf, topg);
2606  topcube = manager->perm[cube->index];
2607 
2608  if (topcube < top) {
2609  return(cuddBddXorExistAbstractRecur(manager, f, g, cuddT(cube)));
2610  }
2611  /* Now, topcube >= top. */
2612 
2613  if (topf == top) {
2614  index = F->index;
2615  fv = cuddT(F);
2616  fnv = cuddE(F);
2617  if (Cudd_IsComplement(f)) {
2618  fv = Cudd_Not(fv);
2619  fnv = Cudd_Not(fnv);
2620  }
2621  } else {
2622  index = G->index;
2623  fv = fnv = f;
2624  }
2625 
2626  if (topg == top) {
2627  gv = cuddT(G);
2628  gnv = cuddE(G);
2629  if (Cudd_IsComplement(g)) {
2630  gv = Cudd_Not(gv);
2631  gnv = Cudd_Not(gnv);
2632  }
2633  } else {
2634  gv = gnv = g;
2635  }
2636 
2637  if (topcube == top) {
2638  Cube = cuddT(cube);
2639  } else {
2640  Cube = cube;
2641  }
2642 
2643  t = cuddBddXorExistAbstractRecur(manager, fv, gv, Cube);
2644  if (t == NULL) return(NULL);
2645 
2646  /* Special case: 1 OR anything = 1. Hence, no need to compute
2647  ** the else branch if t is 1.
2648  */
2649  if (t == one && topcube == top) {
2650  cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, one);
2651  return(one);
2652  }
2653  cuddRef(t);
2654 
2655  e = cuddBddXorExistAbstractRecur(manager, fnv, gnv, Cube);
2656  if (e == NULL) {
2657  Cudd_IterDerefBdd(manager, t);
2658  return(NULL);
2659  }
2660  cuddRef(e);
2661 
2662  if (topcube == top) { /* abstract */
2663  r = cuddBddAndRecur(manager, Cudd_Not(t), Cudd_Not(e));
2664  if (r == NULL) {
2665  Cudd_IterDerefBdd(manager, t);
2666  Cudd_IterDerefBdd(manager, e);
2667  return(NULL);
2668  }
2669  r = Cudd_Not(r);
2670  cuddRef(r);
2671  Cudd_IterDerefBdd(manager, t);
2672  Cudd_IterDerefBdd(manager, e);
2673  cuddDeref(r);
2674  } else if (t == e) {
2675  r = t;
2676  cuddDeref(t);
2677  cuddDeref(e);
2678  } else {
2679  if (Cudd_IsComplement(t)) {
2680  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
2681  if (r == NULL) {
2682  Cudd_IterDerefBdd(manager, t);
2683  Cudd_IterDerefBdd(manager, e);
2684  return(NULL);
2685  }
2686  r = Cudd_Not(r);
2687  } else {
2688  r = cuddUniqueInter(manager,(int)index,t,e);
2689  if (r == NULL) {
2690  Cudd_IterDerefBdd(manager, t);
2691  Cudd_IterDerefBdd(manager, e);
2692  return(NULL);
2693  }
2694  }
2695  cuddDeref(e);
2696  cuddDeref(t);
2697  }
2698  cuddCacheInsert(manager, DD_BDD_XOR_EXIST_ABSTRACT_TAG, f, g, cube, r);
2699  return (r);
2700 
2701 } /* end of cuddBddXorExistAbstractRecur */
#define cuddRef(n)
Definition: cuddInt.h:557
DdNode * cuddBddExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *cube)
Definition: cuddInt.c:2437
#define cuddDeref(n)
Definition: cuddInt.h:577
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:4413
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14090
#define DD_BDD_XOR_EXIST_ABSTRACT_TAG
Definition: cuddInt.h:175
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddInt.c:4283
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3761
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633
int * perm
Definition: cuddInt.h:369
DdNode * cuddBddXorExistAbstractRecur(DdManager *manager, DdNode *f, DdNode *g, DdNode *cube)
Definition: cuddInt.c:2547

◆ cuddBddXorRecur()

DdNode* cuddBddXorRecur ( DdManager manager,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Implements the recursive step of Cudd_bddXor.]

Description [Implements the recursive step of Cudd_bddXor by taking the exclusive OR of two BDDs. Returns a pointer to the result is successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_bddXor]

Definition at line 3761 of file cuddInt.c.

3765 {
3766  DdNode *fv, *fnv, *G, *gv, *gnv;
3767  DdNode *one, *zero, *r, *t, *e;
3768  unsigned int topf, topg, index;
3769 
3770  statLine(manager);
3771  one = DD_ONE(manager);
3772  zero = Cudd_Not(one);
3773 
3774  /* Terminal cases. */
3775  if (f == g) return(zero);
3776  if (f == Cudd_Not(g)) return(one);
3777  if (f > g) { /* Try to increase cache efficiency and simplify tests. */
3778  DdNode *tmp = f;
3779  f = g;
3780  g = tmp;
3781  }
3782  if (g == zero) return(f);
3783  if (g == one) return(Cudd_Not(f));
3784  if (Cudd_IsComplement(f)) {
3785  f = Cudd_Not(f);
3786  g = Cudd_Not(g);
3787  }
3788  /* Now the first argument is regular. */
3789  if (f == one) return(Cudd_Not(g));
3790 
3791  /* At this point f and g are not constant. */
3792 
3793  /* Check cache. */
3794  r = cuddCacheLookup2(manager, Cudd_bddXor, f, g);
3795  if (r != NULL) return(r);
3796 
3797  /* Here we can skip the use of cuddI, because the operands are known
3798  ** to be non-constant.
3799  */
3800  topf = manager->perm[f->index];
3801  G = Cudd_Regular(g);
3802  topg = manager->perm[G->index];
3803 
3804  /* Compute cofactors. */
3805  if (topf <= topg) {
3806  index = f->index;
3807  fv = cuddT(f);
3808  fnv = cuddE(f);
3809  } else {
3810  index = G->index;
3811  fv = fnv = f;
3812  }
3813 
3814  if (topg <= topf) {
3815  gv = cuddT(G);
3816  gnv = cuddE(G);
3817  if (Cudd_IsComplement(g)) {
3818  gv = Cudd_Not(gv);
3819  gnv = Cudd_Not(gnv);
3820  }
3821  } else {
3822  gv = gnv = g;
3823  }
3824 
3825  t = cuddBddXorRecur(manager, fv, gv);
3826  if (t == NULL) return(NULL);
3827  cuddRef(t);
3828 
3829  e = cuddBddXorRecur(manager, fnv, gnv);
3830  if (e == NULL) {
3831  Cudd_IterDerefBdd(manager, t);
3832  return(NULL);
3833  }
3834  cuddRef(e);
3835 
3836  if (t == e) {
3837  r = t;
3838  } else {
3839  if (Cudd_IsComplement(t)) {
3840  r = cuddUniqueInter(manager,(int)index,Cudd_Not(t),Cudd_Not(e));
3841  if (r == NULL) {
3842  Cudd_IterDerefBdd(manager, t);
3843  Cudd_IterDerefBdd(manager, e);
3844  return(NULL);
3845  }
3846  r = Cudd_Not(r);
3847  } else {
3848  r = cuddUniqueInter(manager,(int)index,t,e);
3849  if (r == NULL) {
3850  Cudd_IterDerefBdd(manager, t);
3851  Cudd_IterDerefBdd(manager, e);
3852  return(NULL);
3853  }
3854  }
3855  }
3856  cuddDeref(e);
3857  cuddDeref(t);
3858  cuddCacheInsert2(manager, Cudd_bddXor, f, g, r);
3859  return(r);
3860 
3861 } /* end of cuddBddXorRecur */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
DdNode * Cudd_bddXor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:3253
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14090
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562
DdNode * cuddBddXorRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3761
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329

◆ cuddCacheFlush()

void cuddCacheFlush ( DdManager table)

Function********************************************************************

Synopsis [Flushes the cache.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 5070 of file cuddInt.c.

5072 {
5073  int i, slots;
5074  DdCache *cache;
5075 
5076  slots = table->cacheSlots;
5077  cache = table->cache;
5078  for (i = 0; i < slots; i++) {
5079  table->cachedeletions += cache[i].data != NULL;
5080  cache[i].data = NULL;
5081  }
5082  table->cacheLastInserts = table->cacheinserts;
5083 
5084  return;
5085 
5086 } /* end of cuddCacheFlush */
DdNode * data
Definition: cuddInt.h:304
double cacheinserts
Definition: cuddInt.h:438
unsigned int cacheSlots
Definition: cuddInt.h:337
DdCache * cache
Definition: cuddInt.h:336
double cacheLastInserts
Definition: cuddInt.h:439
double cachedeletions
Definition: cuddInt.h:440

◆ cuddCacheInsert()

void cuddCacheInsert ( DdManager table,
ptruint  op,
DdNode f,
DdNode g,
DdNode h,
DdNode data 
)

Function********************************************************************

Synopsis [Inserts a result in the cache for a function with three operands.]

Description [Inserts a result in the cache for a function with three operands. The operator tag (see CUDD/cuddInt.h for details) is split and stored into unused bits of the first two pointers.]

SideEffects [None]

SeeAlso [cuddCacheInsert2 cuddCacheInsert1]

Definition at line 4283 of file cuddInt.c.

4290 {
4291  int posn;
4292  register DdCache *entry;
4293  ptruint uf, ug, uh;
4294 
4295  uf = (ptruint) f | (op & 0xe);
4296  ug = (ptruint) g | (op >> 4);
4297  uh = (ptruint) h;
4298 
4299  posn = ddCHash2(uh,uf,ug,table->cacheShift);
4300  entry = &table->cache[posn];
4301 
4302  table->cachecollisions += entry->data != NULL;
4303  table->cacheinserts++;
4304 
4305  entry->f = (DdNode *) uf;
4306  entry->g = (DdNode *) ug;
4307  entry->h = uh;
4308  entry->data = data;
4309 #ifdef DD_CACHE_PROFILE
4310  entry->count++;
4311 #endif
4312 
4313 } /* end of cuddCacheInsert */
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:264
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
DdNode * g
Definition: cuddInt.h:302
double cachecollisions
Definition: cuddInt.h:437
double cacheinserts
Definition: cuddInt.h:438
DdCache * cache
Definition: cuddInt.h:336
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
int cacheShift
Definition: cuddInt.h:338
static int * entry
Definition: cuddInt.c:8422

◆ cuddCacheInsert1()

void cuddCacheInsert1 ( DdManager table,
DD_CTFP1  op,
DdNode f,
DdNode data 
)

Function********************************************************************

Synopsis [Inserts a result in the cache for a function with two operands.]

Description []

SideEffects [None]

SeeAlso [cuddCacheInsert cuddCacheInsert2]

Definition at line 4371 of file cuddInt.c.

4376 {
4377  int posn;
4378  register DdCache *entry;
4379 
4380  posn = ddCHash2(op,f,f,table->cacheShift);
4381  entry = &table->cache[posn];
4382 
4383  if (entry->data != NULL) {
4384  table->cachecollisions++;
4385  }
4386  table->cacheinserts++;
4387 
4388  entry->f = f;
4389  entry->g = f;
4390  entry->h = (ptruint) op;
4391  entry->data = data;
4392 #ifdef DD_CACHE_PROFILE
4393  entry->count++;
4394 #endif
4395 
4396 } /* end of cuddCacheInsert1 */
DdNode * f
Definition: cuddInt.h:302
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
DdNode * g
Definition: cuddInt.h:302
double cachecollisions
Definition: cuddInt.h:437
double cacheinserts
Definition: cuddInt.h:438
DdCache * cache
Definition: cuddInt.h:336
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
int cacheShift
Definition: cuddInt.h:338
static int * entry
Definition: cuddInt.c:8422

◆ cuddCacheInsert2()

void cuddCacheInsert2 ( DdManager table,
DD_CTFP  op,
DdNode f,
DdNode g,
DdNode data 
)

Function********************************************************************

Synopsis [Inserts a result in the cache for a function with two operands.]

Description []

SideEffects [None]

SeeAlso [cuddCacheInsert cuddCacheInsert1]

Definition at line 4329 of file cuddInt.c.

4335 {
4336  int posn;
4337  register DdCache *entry;
4338 
4339  posn = ddCHash2(op,f,g,table->cacheShift);
4340  entry = &table->cache[posn];
4341 
4342  if (entry->data != NULL) {
4343  table->cachecollisions++;
4344  }
4345  table->cacheinserts++;
4346 
4347  entry->f = f;
4348  entry->g = g;
4349  entry->h = (ptruint) op;
4350  entry->data = data;
4351 #ifdef DD_CACHE_PROFILE
4352  entry->count++;
4353 #endif
4354 
4355 } /* end of cuddCacheInsert2 */
DdNode * f
Definition: cuddInt.h:302
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
DdNode * g
Definition: cuddInt.h:302
double cachecollisions
Definition: cuddInt.h:437
double cacheinserts
Definition: cuddInt.h:438
DdCache * cache
Definition: cuddInt.h:336
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
int cacheShift
Definition: cuddInt.h:338
static int * entry
Definition: cuddInt.c:8422

◆ cuddCacheLookup()

DdNode* cuddCacheLookup ( DdManager table,
ptruint  op,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Looks up in the cache for the result of op applied to f, g, and h.]

Description [Returns the result if found; it returns NULL if no result is found.]

SideEffects [None]

SeeAlso [cuddCacheLookup2 cuddCacheLookup1]

Definition at line 4413 of file cuddInt.c.

4419 {
4420  int posn;
4421  DdCache *en,*cache;
4422  DdNode *data;
4423  ptruint uf, ug, uh;
4424 
4425  uf = (ptruint) f | (op & 0xe);
4426  ug = (ptruint) g | (op >> 4);
4427  uh = (ptruint) h;
4428 
4429  cache = table->cache;
4430 #ifdef DD_DEBUG
4431  if (cache == NULL) {
4432  return(NULL);
4433  }
4434 #endif
4435 
4436  posn = ddCHash2(uh,uf,ug,table->cacheShift);
4437  en = &cache[posn];
4438  if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug &&
4439  en->h==uh) {
4440  data = Cudd_Regular(en->data);
4441  table->cacheHits++;
4442  if (data->ref == 0) {
4443  cuddReclaim(table,data);
4444  }
4445  return(en->data);
4446  }
4447 
4448  /* Cache miss: decide whether to resize. */
4449  table->cacheMisses++;
4450 
4451  if (table->cacheSlack >= 0 &&
4452  table->cacheHits > table->cacheMisses * table->minHit) {
4453  cuddCacheResize(table);
4454  }
4455 
4456  return(NULL);
4457 
4458 } /* end of cuddCacheLookup */
DdHalfWord ref
Definition: cudd.h:266
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:264
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
#define Cudd_Regular(node)
Definition: cudd.h:373
DdNode * g
Definition: cuddInt.h:302
void cuddCacheResize(DdManager *table)
Definition: cuddInt.c:4955
DdCache * cache
Definition: cuddInt.h:336
double cacheHits
Definition: cuddInt.h:340
int cacheSlack
Definition: cuddInt.h:342
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddInt.c:14223

◆ cuddCacheLookup1()

DdNode* cuddCacheLookup1 ( DdManager table,
DD_CTFP1  op,
DdNode f 
)

Function********************************************************************

Synopsis [Looks up in the cache for the result of op applied to f.]

Description [Returns the result if found; it returns NULL if no result is found.]

SideEffects [None]

SeeAlso [cuddCacheLookup cuddCacheLookup2]

Definition at line 4591 of file cuddInt.c.

4595 {
4596  int posn;
4597  DdCache *en,*cache;
4598  DdNode *data;
4599 
4600  cache = table->cache;
4601 #ifdef DD_DEBUG
4602  if (cache == NULL) {
4603  return(NULL);
4604  }
4605 #endif
4606 
4607  posn = ddCHash2(op,f,f,table->cacheShift);
4608  en = &cache[posn];
4609  if (en->data != NULL && en->f==f && en->h==(ptruint)op) {
4610  data = Cudd_Regular(en->data);
4611  table->cacheHits++;
4612  if (data->ref == 0) {
4613  cuddReclaim(table,data);
4614  }
4615  return(en->data);
4616  }
4617 
4618  /* Cache miss: decide whether to resize. */
4619  table->cacheMisses++;
4620 
4621  if (table->cacheSlack >= 0 &&
4622  table->cacheHits > table->cacheMisses * table->minHit) {
4623  cuddCacheResize(table);
4624  }
4625 
4626  return(NULL);
4627 
4628 } /* end of cuddCacheLookup1 */
DdHalfWord ref
Definition: cudd.h:266
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:264
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
#define Cudd_Regular(node)
Definition: cudd.h:373
void cuddCacheResize(DdManager *table)
Definition: cuddInt.c:4955
DdCache * cache
Definition: cuddInt.h:336
double cacheHits
Definition: cuddInt.h:340
int cacheSlack
Definition: cuddInt.h:342
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddInt.c:14223

◆ cuddCacheLookup1Zdd()

DdNode* cuddCacheLookup1Zdd ( DdManager table,
DD_CTFP1  op,
DdNode f 
)

Function********************************************************************

Synopsis [Looks up in the cache for the result of op applied to f.]

Description [Returns the result if found; it returns NULL if no result is found.]

SideEffects [None]

SeeAlso [cuddCacheLookupZdd cuddCacheLookup2Zdd]

Definition at line 4699 of file cuddInt.c.

4703 {
4704  int posn;
4705  DdCache *en,*cache;
4706  DdNode *data;
4707 
4708  cache = table->cache;
4709 #ifdef DD_DEBUG
4710  if (cache == NULL) {
4711  return(NULL);
4712  }
4713 #endif
4714 
4715  posn = ddCHash2(op,f,f,table->cacheShift);
4716  en = &cache[posn];
4717  if (en->data != NULL && en->f==f && en->h==(ptruint)op) {
4718  data = Cudd_Regular(en->data);
4719  table->cacheHits++;
4720  if (data->ref == 0) {
4721  cuddReclaimZdd(table,data);
4722  }
4723  return(en->data);
4724  }
4725 
4726  /* Cache miss: decide whether to resize. */
4727  table->cacheMisses++;
4728 
4729  if (table->cacheSlack >= 0 &&
4730  table->cacheHits > table->cacheMisses * table->minHit) {
4731  cuddCacheResize(table);
4732  }
4733 
4734  return(NULL);
4735 
4736 } /* end of cuddCacheLookup1Zdd */
DdHalfWord ref
Definition: cudd.h:266
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:264
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
#define Cudd_Regular(node)
Definition: cudd.h:373
void cuddCacheResize(DdManager *table)
Definition: cuddInt.c:4955
DdCache * cache
Definition: cuddInt.h:336
double cacheHits
Definition: cuddInt.h:340
int cacheSlack
Definition: cuddInt.h:342
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
void cuddReclaimZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14277
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338

◆ cuddCacheLookup2()

DdNode* cuddCacheLookup2 ( DdManager table,
DD_CTFP  op,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Looks up in the cache for the result of op applied to f and g.]

Description [Returns the result if found; it returns NULL if no result is found.]

SideEffects [None]

SeeAlso [cuddCacheLookup cuddCacheLookup1]

Definition at line 4537 of file cuddInt.c.

4542 {
4543  int posn;
4544  DdCache *en,*cache;
4545  DdNode *data;
4546 
4547  cache = table->cache;
4548 #ifdef DD_DEBUG
4549  if (cache == NULL) {
4550  return(NULL);
4551  }
4552 #endif
4553 
4554  posn = ddCHash2(op,f,g,table->cacheShift);
4555  en = &cache[posn];
4556  if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) {
4557  data = Cudd_Regular(en->data);
4558  table->cacheHits++;
4559  if (data->ref == 0) {
4560  cuddReclaim(table,data);
4561  }
4562  return(en->data);
4563  }
4564 
4565  /* Cache miss: decide whether to resize. */
4566  table->cacheMisses++;
4567 
4568  if (table->cacheSlack >= 0 &&
4569  table->cacheHits > table->cacheMisses * table->minHit) {
4570  cuddCacheResize(table);
4571  }
4572 
4573  return(NULL);
4574 
4575 } /* end of cuddCacheLookup2 */
DdHalfWord ref
Definition: cudd.h:266
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:264
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
#define Cudd_Regular(node)
Definition: cudd.h:373
DdNode * g
Definition: cuddInt.h:302
void cuddCacheResize(DdManager *table)
Definition: cuddInt.c:4955
DdCache * cache
Definition: cuddInt.h:336
double cacheHits
Definition: cuddInt.h:340
int cacheSlack
Definition: cuddInt.h:342
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddInt.c:14223

◆ cuddCacheLookup2Zdd()

DdNode* cuddCacheLookup2Zdd ( DdManager table,
DD_CTFP  op,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Looks up in the cache for the result of op applied to f and g.]

Description [Returns the result if found; it returns NULL if no result is found.]

SideEffects [None]

SeeAlso [cuddCacheLookupZdd cuddCacheLookup1Zdd]

Definition at line 4645 of file cuddInt.c.

4650 {
4651  int posn;
4652  DdCache *en,*cache;
4653  DdNode *data;
4654 
4655  cache = table->cache;
4656 #ifdef DD_DEBUG
4657  if (cache == NULL) {
4658  return(NULL);
4659  }
4660 #endif
4661 
4662  posn = ddCHash2(op,f,g,table->cacheShift);
4663  en = &cache[posn];
4664  if (en->data != NULL && en->f==f && en->g==g && en->h==(ptruint)op) {
4665  data = Cudd_Regular(en->data);
4666  table->cacheHits++;
4667  if (data->ref == 0) {
4668  cuddReclaimZdd(table,data);
4669  }
4670  return(en->data);
4671  }
4672 
4673  /* Cache miss: decide whether to resize. */
4674  table->cacheMisses++;
4675 
4676  if (table->cacheSlack >= 0 &&
4677  table->cacheHits > table->cacheMisses * table->minHit) {
4678  cuddCacheResize(table);
4679  }
4680 
4681  return(NULL);
4682 
4683 } /* end of cuddCacheLookup2Zdd */
DdHalfWord ref
Definition: cudd.h:266
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:264
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
#define Cudd_Regular(node)
Definition: cudd.h:373
DdNode * g
Definition: cuddInt.h:302
void cuddCacheResize(DdManager *table)
Definition: cuddInt.c:4955
DdCache * cache
Definition: cuddInt.h:336
double cacheHits
Definition: cuddInt.h:340
int cacheSlack
Definition: cuddInt.h:342
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
void cuddReclaimZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14277
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338

◆ cuddCacheLookupZdd()

DdNode* cuddCacheLookupZdd ( DdManager table,
ptruint  op,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Looks up in the cache for the result of op applied to f, g, and h.]

Description [Returns the result if found; it returns NULL if no result is found.]

SideEffects [None]

SeeAlso [cuddCacheLookup2Zdd cuddCacheLookup1Zdd]

Definition at line 4475 of file cuddInt.c.

4481 {
4482  int posn;
4483  DdCache *en,*cache;
4484  DdNode *data;
4485  ptruint uf, ug, uh;
4486 
4487  uf = (ptruint) f | (op & 0xe);
4488  ug = (ptruint) g | (op >> 4);
4489  uh = (ptruint) h;
4490 
4491  cache = table->cache;
4492 #ifdef DD_DEBUG
4493  if (cache == NULL) {
4494  return(NULL);
4495  }
4496 #endif
4497 
4498  posn = ddCHash2(uh,uf,ug,table->cacheShift);
4499  en = &cache[posn];
4500  if (en->data != NULL && en->f==(DdNodePtr)uf && en->g==(DdNodePtr)ug &&
4501  en->h==uh) {
4502  data = Cudd_Regular(en->data);
4503  table->cacheHits++;
4504  if (data->ref == 0) {
4505  cuddReclaimZdd(table,data);
4506  }
4507  return(en->data);
4508  }
4509 
4510  /* Cache miss: decide whether to resize. */
4511  table->cacheMisses++;
4512 
4513  if (table->cacheSlack >= 0 &&
4514  table->cacheHits > table->cacheMisses * table->minHit) {
4515  cuddCacheResize(table);
4516  }
4517 
4518  return(NULL);
4519 
4520 } /* end of cuddCacheLookupZdd */
DdHalfWord ref
Definition: cudd.h:266
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:264
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
#define Cudd_Regular(node)
Definition: cudd.h:373
DdNode * g
Definition: cuddInt.h:302
void cuddCacheResize(DdManager *table)
Definition: cuddInt.c:4955
DdCache * cache
Definition: cuddInt.h:336
double cacheHits
Definition: cuddInt.h:340
int cacheSlack
Definition: cuddInt.h:342
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
void cuddReclaimZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14277
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338

◆ cuddCacheProfile()

int cuddCacheProfile ( DdManager table,
FILE *  fp 
)

Function********************************************************************

Synopsis [Computes and prints a profile of the cache usage.]

Description [Computes and prints a profile of the cache usage. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 4815 of file cuddInt.c.

4818 {
4819  DdCache *cache = table->cache;
4820  int slots = table->cacheSlots;
4821  int nzeroes = 0;
4822  int i, retval;
4823  double exUsed;
4824 
4825 #ifdef DD_CACHE_PROFILE
4826  double count, mean, meansq, stddev, expected;
4827  long max, min;
4828  int imax, imin;
4829  double *hystogramQ, *hystogramR; /* histograms by quotient and remainder */
4830  int nbins = DD_HYSTO_BINS;
4831  int bin;
4832  long thiscount;
4833  double totalcount, exStddev;
4834 
4835  meansq = mean = expected = 0.0;
4836  max = min = (long) cache[0].count;
4837  imax = imin = 0;
4838  totalcount = 0.0;
4839 
4840  hystogramQ = ALLOC(double, nbins);
4841  if (hystogramQ == NULL) {
4842  table->errorCode = CUDD_MEMORY_OUT;
4843  return(0);
4844  }
4845  hystogramR = ALLOC(double, nbins);
4846  if (hystogramR == NULL) {
4847  FREE(hystogramQ);
4848  table->errorCode = CUDD_MEMORY_OUT;
4849  return(0);
4850  }
4851  for (i = 0; i < nbins; i++) {
4852  hystogramQ[i] = 0;
4853  hystogramR[i] = 0;
4854  }
4855 
4856  for (i = 0; i < slots; i++) {
4857  thiscount = (long) cache[i].count;
4858  if (thiscount > max) {
4859  max = thiscount;
4860  imax = i;
4861  }
4862  if (thiscount < min) {
4863  min = thiscount;
4864  imin = i;
4865  }
4866  if (thiscount == 0) {
4867  nzeroes++;
4868  }
4869  count = (double) thiscount;
4870  mean += count;
4871  meansq += count * count;
4872  totalcount += count;
4873  expected += count * (double) i;
4874  bin = (i * nbins) / slots;
4875  hystogramQ[bin] += (double) thiscount;
4876  bin = i % nbins;
4877  hystogramR[bin] += (double) thiscount;
4878  }
4879  mean /= (double) slots;
4880  meansq /= (double) slots;
4881 
4882  /* Compute the standard deviation from both the data and the
4883  ** theoretical model for a random distribution. */
4884  stddev = sqrt(meansq - mean*mean);
4885  exStddev = sqrt((1 - 1/(double) slots) * totalcount / (double) slots);
4886 
4887  retval = fprintf(fp,"Cache average accesses = %g\n", mean);
4888  if (retval == EOF) return(0);
4889  retval = fprintf(fp,"Cache access standard deviation = %g ", stddev);
4890  if (retval == EOF) return(0);
4891  retval = fprintf(fp,"(expected = %g)\n", exStddev);
4892  if (retval == EOF) return(0);
4893  retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax);
4894  if (retval == EOF) return(0);
4895  retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin);
4896  if (retval == EOF) return(0);
4897  exUsed = 100.0 * (1.0 - exp(-totalcount / (double) slots));
4898  retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n",
4899  100.0 - (double) nzeroes * 100.0 / (double) slots,
4900  exUsed);
4901  if (retval == EOF) return(0);
4902 
4903  if (totalcount > 0) {
4904  expected /= totalcount;
4905  retval = fprintf(fp,"Cache access hystogram for %d bins", nbins);
4906  if (retval == EOF) return(0);
4907  retval = fprintf(fp," (expected bin value = %g)\nBy quotient:",
4908  expected);
4909  if (retval == EOF) return(0);
4910  for (i = nbins - 1; i>=0; i--) {
4911  retval = fprintf(fp," %.0f", hystogramQ[i]);
4912  if (retval == EOF) return(0);
4913  }
4914  retval = fprintf(fp,"\nBy residue: ");
4915  if (retval == EOF) return(0);
4916  for (i = nbins - 1; i>=0; i--) {
4917  retval = fprintf(fp," %.0f", hystogramR[i]);
4918  if (retval == EOF) return(0);
4919  }
4920  retval = fprintf(fp,"\n");
4921  if (retval == EOF) return(0);
4922  }
4923 
4924  FREE(hystogramQ);
4925  FREE(hystogramR);
4926 #else
4927  for (i = 0; i < slots; i++) {
4928  nzeroes += cache[i].h == 0;
4929  }
4930  exUsed = 100.0 *
4931  (1.0 - exp(-(table->cacheinserts - table->cacheLastInserts) /
4932  (double) slots));
4933  retval = fprintf(fp,"Cache used slots = %.2f%% (expected %.2f%%)\n",
4934  100.0 - (double) nzeroes * 100.0 / (double) slots,
4935  exUsed);
4936  if (retval == EOF) return(0);
4937 #endif
4938  return(1);
4939 
4940 } /* end of cuddCacheProfile */
#define FREE(obj)
Definition: util.h:80
ptruint h
Definition: cuddInt.h:303
double cacheinserts
Definition: cuddInt.h:438
unsigned int cacheSlots
Definition: cuddInt.h:337
#define ALLOC(type, num)
Definition: util.h:76
DdCache * cache
Definition: cuddInt.h:336
double cacheLastInserts
Definition: cuddInt.h:439
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddCacheResize()

void cuddCacheResize ( DdManager table)

Function********************************************************************

Synopsis [Resizes the cache.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 4955 of file cuddInt.c.

4957 {
4958  DdCache *cache, *oldcache, *oldacache, *entry, *old;
4959  int i;
4960  int posn, shift;
4961  unsigned int slots, oldslots;
4962  double offset;
4963  int moved = 0;
4964  extern DD_OOMFP MMoutOfMemory;
4965  DD_OOMFP saveHandler;
4966 #ifndef DD_CACHE_PROFILE
4967  ptruint misalignment;
4968  DdNodePtr *mem;
4969 #endif
4970 
4971  oldcache = table->cache;
4972  oldacache = table->acache;
4973  oldslots = table->cacheSlots;
4974  slots = table->cacheSlots = oldslots << 1;
4975 
4976 #ifdef DD_VERBOSE
4977  (void) fprintf(table->err,"Resizing the cache from %d to %d entries\n",
4978  oldslots, slots);
4979  (void) fprintf(table->err,
4980  "\thits = %g\tmisses = %g\thit ratio = %5.3f\n",
4981  table->cacheHits, table->cacheMisses,
4982  table->cacheHits / (table->cacheHits + table->cacheMisses));
4983 #endif
4984 
4985  saveHandler = MMoutOfMemory;
4986  MMoutOfMemory = Cudd_OutOfMem;
4987  table->acache = cache = ALLOC(DdCache,slots+1);
4988  MMoutOfMemory = saveHandler;
4989  /* If we fail to allocate the new table we just give up. */
4990  if (cache == NULL) {
4991 #ifdef DD_VERBOSE
4992  (void) fprintf(table->err,"Resizing failed. Giving up.\n");
4993 #endif
4994  table->cacheSlots = oldslots;
4995  table->acache = oldacache;
4996  /* Do not try to resize again. */
4997  table->maxCacheHard = oldslots - 1;
4998  table->cacheSlack = - (int) (oldslots + 1);
4999  return;
5000  }
5001  /* If the size of the cache entry is a power of 2, we want to
5002  ** enforce alignment to that power of two. This happens when
5003  ** DD_CACHE_PROFILE is not defined. */
5004 #ifdef DD_CACHE_PROFILE
5005  table->cache = cache;
5006 #else
5007  mem = (DdNodePtr *) cache;
5008  misalignment = (ptruint) mem & (sizeof(DdCache) - 1);
5009  mem += (sizeof(DdCache) - misalignment) / sizeof(DdNodePtr);
5010  table->cache = cache = (DdCache *) mem;
5011  assert(((ptruint) table->cache & (sizeof(DdCache) - 1)) == 0);
5012 #endif
5013  shift = --(table->cacheShift);
5014  table->memused += (slots - oldslots) * sizeof(DdCache);
5015  table->cacheSlack -= slots; /* need these many slots to double again */
5016 
5017  /* Clear new cache. */
5018  for (i = 0; (unsigned) i < slots; i++) {
5019  cache[i].data = NULL;
5020  cache[i].h = 0;
5021 #ifdef DD_CACHE_PROFILE
5022  cache[i].count = 0;
5023 #endif
5024  }
5025 
5026  /* Copy from old cache to new one. */
5027  for (i = 0; (unsigned) i < oldslots; i++) {
5028  old = &oldcache[i];
5029  if (old->data != NULL) {
5030  posn = ddCHash2(old->h,old->f,old->g,shift);
5031  entry = &cache[posn];
5032  entry->f = old->f;
5033  entry->g = old->g;
5034  entry->h = old->h;
5035  entry->data = old->data;
5036 #ifdef DD_CACHE_PROFILE
5037  entry->count = 1;
5038 #endif
5039  moved++;
5040  }
5041  }
5042 
5043  FREE(oldacache);
5044 
5045  /* Reinitialize measurements so as to avoid division by 0 and
5046  ** immediate resizing.
5047  */
5048  offset = (double) (int) (slots * table->minHit + 1);
5049  table->totCacheMisses += table->cacheMisses - offset;
5050  table->cacheMisses = offset;
5051  table->totCachehits += table->cacheHits;
5052  table->cacheHits = 0;
5053  table->cacheLastInserts = table->cacheinserts - (double) moved;
5054 
5055 } /* end of cuddCacheResize */
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
DdNode * data
Definition: cuddInt.h:304
#define assert(ex)
Definition: util.h:141
unsigned int maxCacheHard
Definition: cuddInt.h:343
ptruint h
Definition: cuddInt.h:303
FILE * err
Definition: cuddInt.h:424
DdNode * g
Definition: cuddInt.h:302
DdNode * DdNodePtr
Definition: cuddInt.h:253
double cacheinserts
Definition: cuddInt.h:438
void(* DD_OOMFP)(long)
Definition: cudd.h:300
unsigned int cacheSlots
Definition: cuddInt.h:337
#define ALLOC(type, num)
Definition: util.h:76
DdCache * cache
Definition: cuddInt.h:336
double totCacheMisses
Definition: cuddInt.h:436
double cacheLastInserts
Definition: cuddInt.h:439
double cacheHits
Definition: cuddInt.h:340
int cacheSlack
Definition: cuddInt.h:342
void(* MMoutOfMemory)(long)
Definition: util.c:105
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned long memused
Definition: cuddInt.h:429
unsigned int ptruint
Definition: cuddInt.h:250
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338
void Cudd_OutOfMem(long size)
Definition: cuddInt.c:22982
static int * entry
Definition: cuddInt.c:8422
DdCache * acache
Definition: cuddInt.h:335
struct DdCache DdCache
double totCachehits
Definition: cuddInt.h:435

◆ cuddClearDeathRow()

void cuddClearDeathRow ( DdManager table)

Function********************************************************************

Synopsis [Clears the death row.]

Description []

SideEffects [None]

SeeAlso [Cudd_DelayedDerefBdd Cudd_IterDerefBdd Cudd_CheckZeroRef cuddGarbageCollect]

Definition at line 14365 of file cuddInt.c.

14367 {
14368 #ifndef DD_NO_DEATH_ROW
14369  int i;
14370 
14371  for (i = 0; i < table->deathRowDepth; i++) {
14372  if (table->deathRow[i] == NULL) break;
14373  Cudd_IterDerefBdd(table,table->deathRow[i]);
14374  table->deathRow[i] = NULL;
14375  }
14376 #ifdef DD_DEBUG
14377  for (; i < table->deathRowDepth; i++) {
14378  assert(table->deathRow[i] == NULL);
14379  }
14380 #endif
14381  table->nextDead = 0;
14382 #endif
14383 
14384 } /* end of cuddClearDeathRow */
#define assert(ex)
Definition: util.h:141
DdNode ** deathRow
Definition: cuddInt.h:384
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14090
int nextDead
Definition: cuddInt.h:386
int deathRowDepth
Definition: cuddInt.h:385

◆ cuddCofactorRecur()

DdNode* cuddCofactorRecur ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_Cofactor.]

Description [Performs the recursive step of Cudd_Cofactor. Returns a pointer to the cofactor if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_Cofactor]

Definition at line 6226 of file cuddInt.c.

6230 {
6231  DdNode *one,*zero,*F,*G,*g1,*g0,*f1,*f0,*t,*e,*r;
6232  unsigned int topf,topg;
6233  int comple;
6234 
6235  statLine(dd);
6236  F = Cudd_Regular(f);
6237  if (cuddIsConstant(F)) return(f);
6238 
6239  one = DD_ONE(dd);
6240 
6241  /* The invariant g != 0 is true on entry to this procedure and is
6242  ** recursively maintained by it. Therefore it suffices to test g
6243  ** against one to make sure it is not constant.
6244  */
6245  if (g == one) return(f);
6246  /* From now on, f and g are known not to be constants. */
6247 
6248  comple = f != F;
6249  r = cuddCacheLookup2(dd,Cudd_Cofactor,F,g);
6250  if (r != NULL) {
6251  return(Cudd_NotCond(r,comple));
6252  }
6253 
6254  topf = dd->perm[F->index];
6255  G = Cudd_Regular(g);
6256  topg = dd->perm[G->index];
6257 
6258  /* We take the cofactors of F because we are going to rely on
6259  ** the fact that the cofactors of the complement are the complements
6260  ** of the cofactors to better utilize the cache. Variable comple
6261  ** remembers whether we have to complement the result or not.
6262  */
6263  if (topf <= topg) {
6264  f1 = cuddT(F); f0 = cuddE(F);
6265  } else {
6266  f1 = f0 = F;
6267  }
6268  if (topg <= topf) {
6269  g1 = cuddT(G); g0 = cuddE(G);
6270  if (g != G) { g1 = Cudd_Not(g1); g0 = Cudd_Not(g0); }
6271  } else {
6272  g1 = g0 = g;
6273  }
6274 
6275  zero = Cudd_Not(one);
6276  if (topf >= topg) {
6277  if (g0 == zero || g0 == DD_ZERO(dd)) {
6278  r = cuddCofactorRecur(dd, f1, g1);
6279  } else if (g1 == zero || g1 == DD_ZERO(dd)) {
6280  r = cuddCofactorRecur(dd, f0, g0);
6281  } else {
6282  (void) fprintf(dd->out,
6283  "Cudd_Cofactor: Invalid restriction 2\n");
6285  return(NULL);
6286  }
6287  if (r == NULL) return(NULL);
6288  } else /* if (topf < topg) */ {
6289  t = cuddCofactorRecur(dd, f1, g);
6290  if (t == NULL) return(NULL);
6291  cuddRef(t);
6292  e = cuddCofactorRecur(dd, f0, g);
6293  if (e == NULL) {
6294  Cudd_RecursiveDeref(dd, t);
6295  return(NULL);
6296  }
6297  cuddRef(e);
6298 
6299  if (t == e) {
6300  r = t;
6301  } else if (Cudd_IsComplement(t)) {
6302  r = cuddUniqueInter(dd,(int)F->index,Cudd_Not(t),Cudd_Not(e));
6303  if (r != NULL)
6304  r = Cudd_Not(r);
6305  } else {
6306  r = cuddUniqueInter(dd,(int)F->index,t,e);
6307  }
6308  if (r == NULL) {
6309  Cudd_RecursiveDeref(dd ,e);
6310  Cudd_RecursiveDeref(dd ,t);
6311  return(NULL);
6312  }
6313  cuddDeref(t);
6314  cuddDeref(e);
6315  }
6316 
6317  cuddCacheInsert2(dd,Cudd_Cofactor,F,g,r);
6318 
6319  return(Cudd_NotCond(r,comple));
6320 
6321 } /* end of cuddCofactorRecur */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCofactorRecur(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:6226
#define Cudd_IsComplement(node)
Definition: cudd.h:401
FILE * out
Definition: cuddInt.h:423
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:359
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
int * perm
Definition: cuddInt.h:369
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
DdNode * Cudd_Cofactor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:6119
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddCollectNodes()

int cuddCollectNodes ( DdNode f,
st_table visited 
)

Function********************************************************************

Synopsis [Recursively collects all the nodes of a DD in a symbol table.]

Description [Traverses the DD f and collects all its nodes in a symbol table. f is assumed to be a regular pointer and cuddCollectNodes guarantees this assumption in the recursive calls. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 23013 of file cuddInt.c.

23016 {
23017 DdNode *T, *E;
23018 int retval;
23019 
23020 #ifdef DD_DEBUG
23022 #endif
23023 
23024 /* If already visited, nothing to do. */
23025 if (st_is_member(visited, (char *) f) == 1)
23026 return(1);
23027 
23028 /* Check for abnormal condition that should never happen. */
23029 if (f == NULL)
23030 return(0);
23031 
23032 /* Mark node as visited. */
23033 if (st_add_direct(visited, (char *) f, NULL) == ST_OUT_OF_MEM)
23034 return(0);
23035 
23036 /* Check terminal case. */
23037 if (cuddIsConstant(f))
23038 return(1);
23039 
23040 /* Recursive calls. */
23041 T = cuddT(f);
23042 retval = cuddCollectNodes(T,visited);
23043 if (retval != 1) return(retval);
23044 E = Cudd_Regular(cuddE(f));
23045 retval = cuddCollectNodes(E,visited);
23046 return(retval);
23047 
23048 } /* end of cuddCollectNodes */
Definition: cudd.h:264
int cuddCollectNodes(DdNode *f, st_table *visited)
Definition: cuddInt.c:23013
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:373
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define ST_OUT_OF_MEM
Definition: st.h:41
int st_add_direct(st_table *, void *, void *)
Definition: st.c:395
#define st_is_member(table, key)
Definition: st.h:107
#define cuddE(node)
Definition: cuddInt.h:625

◆ cuddComputeFloorLog2()

int cuddComputeFloorLog2 ( unsigned int  value)

Function********************************************************************

Synopsis [Returns the floor of the logarithm to the base 2.]

Description [Returns the floor of the logarithm to the base 2. The input value is assumed to be greater than 0.]

SideEffects [None]

SeeAlso []

Definition at line 5102 of file cuddInt.c.

5104 {
5105  int floorLog = 0;
5106 #ifdef DD_DEBUG
5107  assert(value > 0);
5108 #endif
5109  while (value > 1) {
5110  floorLog++;
5111  value >>= 1;
5112  }
5113  return(floorLog);
5114 
5115 } /* end of cuddComputeFloorLog2 */
#define assert(ex)
Definition: util.h:141

◆ cuddConstantLookup()

DdNode* cuddConstantLookup ( DdManager table,
ptruint  op,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Looks up in the cache for the result of op applied to f, g, and h.]

Description [Looks up in the cache for the result of op applied to f, g, and h. Assumes that the calling procedure (e.g., Cudd_bddIteConstant) is only interested in whether the result is constant or not. Returns the result if found (possibly DD_NON_CONSTANT); otherwise it returns NULL.]

SideEffects [None]

SeeAlso [cuddCacheLookup]

Definition at line 4756 of file cuddInt.c.

4762 {
4763  int posn;
4764  DdCache *en,*cache;
4765  ptruint uf, ug, uh;
4766 
4767  uf = (ptruint) f | (op & 0xe);
4768  ug = (ptruint) g | (op >> 4);
4769  uh = (ptruint) h;
4770 
4771  cache = table->cache;
4772 #ifdef DD_DEBUG
4773  if (cache == NULL) {
4774  return(NULL);
4775  }
4776 #endif
4777  posn = ddCHash2(uh,uf,ug,table->cacheShift);
4778  en = &cache[posn];
4779 
4780  /* We do not reclaim here because the result should not be
4781  * referenced, but only tested for being a constant.
4782  */
4783  if (en->data != NULL &&
4784  en->f == (DdNodePtr)uf && en->g == (DdNodePtr)ug && en->h == uh) {
4785  table->cacheHits++;
4786  return(en->data);
4787  }
4788 
4789  /* Cache miss: decide whether to resize. */
4790  table->cacheMisses++;
4791 
4792  if (table->cacheSlack >= 0 &&
4793  table->cacheHits > table->cacheMisses * table->minHit) {
4794  cuddCacheResize(table);
4795  }
4796 
4797  return(NULL);
4798 
4799 } /* end of cuddConstantLookup */
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:264
DdNode * data
Definition: cuddInt.h:304
ptruint h
Definition: cuddInt.h:303
DdNode * g
Definition: cuddInt.h:302
void cuddCacheResize(DdManager *table)
Definition: cuddInt.c:4955
DdCache * cache
Definition: cuddInt.h:336
double cacheHits
Definition: cuddInt.h:340
int cacheSlack
Definition: cuddInt.h:342
#define ddCHash2(o, f, g, s)
Definition: cuddInt.h:741
unsigned int ptruint
Definition: cuddInt.h:250
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338

◆ cuddDynamicAllocNode()

DdNode* cuddDynamicAllocNode ( DdManager table)

Function********************************************************************

Synopsis [Dynamically allocates a Node.]

Description [Dynamically allocates a Node. This procedure is similar to cuddAllocNode in Cudd_Table.c, but it does not attempt garbage collection, because during reordering there are no dead nodes. Returns a pointer to a new node if successful; NULL is memory is full.]

SideEffects [None]

SeeAlso [cuddAllocNode]

Definition at line 14727 of file cuddInt.c.

14729 {
14730  int i;
14731  DdNodePtr *mem;
14732  DdNode *list, *node;
14733  extern DD_OOMFP MMoutOfMemory;
14734  DD_OOMFP saveHandler;
14735 
14736  if (table->nextFree == NULL) { /* free list is empty */
14737  /* Try to allocate a new block. */
14738  saveHandler = MMoutOfMemory;
14739  MMoutOfMemory = Cudd_OutOfMem;
14740  mem = (DdNodePtr *) ALLOC(DdNode, DD_MEM_CHUNK + 1);
14741  MMoutOfMemory = saveHandler;
14742  if (mem == NULL && table->stash != NULL) {
14743  FREE(table->stash);
14744  table->stash = NULL;
14745  /* Inhibit resizing of tables. */
14746  table->maxCacheHard = table->cacheSlots - 1;
14747  table->cacheSlack = - (int) (table->cacheSlots + 1);
14748  for (i = 0; i < table->size; i++) {
14749  table->subtables[i].maxKeys <<= 2;
14750  }
14751  mem = (DdNodePtr *) ALLOC(DdNode,DD_MEM_CHUNK + 1);
14752  }
14753  if (mem == NULL) {
14754  /* Out of luck. Call the default handler to do
14755  ** whatever it specifies for a failed malloc. If this
14756  ** handler returns, then set error code, print
14757  ** warning, and return. */
14758  (*MMoutOfMemory)(sizeof(DdNode)*(DD_MEM_CHUNK + 1));
14759  table->errorCode = CUDD_MEMORY_OUT;
14760 #ifdef DD_VERBOSE
14761  (void) fprintf(table->err,
14762  "cuddDynamicAllocNode: out of memory");
14763  (void) fprintf(table->err,"Memory in use = %lu\n",
14764  table->memused);
14765 #endif
14766  return(NULL);
14767  } else { /* successful allocation; slice memory */
14768  unsigned long offset;
14769  table->memused += (DD_MEM_CHUNK + 1) * sizeof(DdNode);
14770  mem[0] = (DdNode *) table->memoryList;
14771  table->memoryList = mem;
14772 
14773  /* Here we rely on the fact that the size of a DdNode is a
14774  ** power of 2 and a multiple of the size of a pointer.
14775  ** If we align one node, all the others will be aligned
14776  ** as well. */
14777  offset = (unsigned long) mem & (sizeof(DdNode) - 1);
14778  mem += (sizeof(DdNode) - offset) / sizeof(DdNodePtr);
14779 #ifdef DD_DEBUG
14780  assert(((unsigned long) mem & (sizeof(DdNode) - 1)) == 0);
14781 #endif
14782  list = (DdNode *) mem;
14783 
14784  i = 1;
14785  do {
14786  list[i - 1].ref = 0;
14787  list[i - 1].next = &list[i];
14788  } while (++i < DD_MEM_CHUNK);
14789 
14790  list[DD_MEM_CHUNK-1].ref = 0;
14791  list[DD_MEM_CHUNK - 1].next = NULL;
14792 
14793  table->nextFree = &list[0];
14794  }
14795  } /* if free list empty */
14796 
14797  node = table->nextFree;
14798  table->nextFree = node->next;
14799  return (node);
14800 
14801 } /* end of cuddDynamicAllocNode */
DdHalfWord ref
Definition: cudd.h:266
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
unsigned int maxCacheHard
Definition: cuddInt.h:343
FILE * err
Definition: cuddInt.h:424
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode * DdNodePtr
Definition: cuddInt.h:253
void(* DD_OOMFP)(long)
Definition: cudd.h:300
struct DdNode DdNode
Definition: cudd.h:256
unsigned int cacheSlots
Definition: cuddInt.h:337
char * stash
Definition: cuddInt.h:382
#define ALLOC(type, num)
Definition: util.h:76
DdNode * next
Definition: cudd.h:267
unsigned int maxKeys
Definition: cuddInt.h:315
int cacheSlack
Definition: cuddInt.h:342
void(* MMoutOfMemory)(long)
Definition: util.c:105
DdNode ** memoryList
Definition: cuddInt.h:380
unsigned long memused
Definition: cuddInt.h:429
DdNode * nextFree
Definition: cuddInt.h:381
void Cudd_OutOfMem(long size)
Definition: cuddInt.c:22982
#define DD_MEM_CHUNK
Definition: cuddInt.h:105
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddEstimateCofactor()

static int cuddEstimateCofactor ( DdManager dd,
st_table table,
DdNode node,
int  i,
int  phase,
DdNode **  ptr 
)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_CofactorEstimate.]

Description [Performs the recursive step of Cudd_CofactorEstimate. Returns an estimate of the number of nodes in the DD of a cofactor of node. Uses the least significant bit of the next field as visited flag. node is supposed to be regular; the invariant is maintained by this procedure.]

SideEffects [None]

SeeAlso []

Definition at line 23328 of file cuddInt.c.

23335 {
23336 int tval, eval, val;
23337 DdNode *ptrT, *ptrE;
23338 
23339 if (Cudd_IsComplement(node->next)) {
23340 if (!st_lookup(table,(char *)node,(char **)ptr)) {
23341 if (st_add_direct(table,(char *)node,(char *)node) ==
23343 return(CUDD_OUT_OF_MEM);
23344 *ptr = node;
23345 }
23346 return(0);
23347 }
23348 node->next = Cudd_Not(node->next);
23349 if (cuddIsConstant(node)) {
23350 *ptr = node;
23351 if (st_add_direct(table,(char *)node,(char *)node) == ST_OUT_OF_MEM)
23352 return(CUDD_OUT_OF_MEM);
23353 return(1);
23354 }
23355 if ((int) node->index == i) {
23356 if (phase == 1) {
23357 *ptr = cuddT(node);
23358 val = ddDagInt(cuddT(node));
23359 } else {
23360 *ptr = cuddE(node);
23361 val = ddDagInt(Cudd_Regular(cuddE(node)));
23362 }
23363 if (node->ref > 1) {
23364 if (st_add_direct(table,(char *)node,(char *)*ptr) ==
23366 return(CUDD_OUT_OF_MEM);
23367 }
23368 return(val);
23369 }
23370 if (dd->perm[node->index] > dd->perm[i]) {
23371 *ptr = node;
23372 tval = ddDagInt(cuddT(node));
23373 eval = ddDagInt(Cudd_Regular(cuddE(node)));
23374 if (node->ref > 1) {
23375 if (st_add_direct(table,(char *)node,(char *)node) ==
23377 return(CUDD_OUT_OF_MEM);
23378 }
23379 val = 1 + tval + eval;
23380 return(val);
23381 }
23382 tval = cuddEstimateCofactor(dd,table,cuddT(node),i,phase,&ptrT);
23383 eval = cuddEstimateCofactor(dd,table,Cudd_Regular(cuddE(node)),i,
23384 phase,&ptrE);
23385 ptrE = Cudd_NotCond(ptrE,Cudd_IsComplement(cuddE(node)));
23386 if (ptrT == ptrE) { /* recombination */
23387 *ptr = ptrT;
23388 val = tval;
23389 if (node->ref > 1) {
23390 if (st_add_direct(table,(char *)node,(char *)*ptr) ==
23392 return(CUDD_OUT_OF_MEM);
23393 }
23394 } else if ((ptrT != cuddT(node) || ptrE != cuddE(node)) &&
23395 (*ptr = cuddUniqueLookup(dd,node->index,ptrT,ptrE)) != NULL) {
23396 if (Cudd_IsComplement((*ptr)->next)) {
23397 val = 0;
23398 } else {
23399 val = 1 + tval + eval;
23400 }
23401 if (node->ref > 1) {
23402 if (st_add_direct(table,(char *)node,(char *)*ptr) ==
23404 return(CUDD_OUT_OF_MEM);
23405 }
23406 } else {
23407 *ptr = node;
23408 val = 1 + tval + eval;
23409 }
23410 return(val);
23411 
23412 } /* end of cuddEstimateCofactor */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
int st_lookup(st_table *, void *, void *)
Definition: st.c:271
static int ddDagInt(DdNode *n)
Definition: cuddInt.c:23253
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_Regular(node)
Definition: cudd.h:373
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode * next
Definition: cudd.h:267
static int cuddEstimateCofactor(DdManager *dd, st_table *table, DdNode *node, int i, int phase, DdNode **ptr)
Definition: cuddInt.c:23328
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define ST_OUT_OF_MEM
Definition: st.h:41
int st_add_direct(st_table *, void *, void *)
Definition: st.c:395
#define cuddE(node)
Definition: cuddInt.h:625
#define Cudd_NotCond(node, c)
Definition: cudd.h:359
int * perm
Definition: cuddInt.h:369
static DdNode * cuddUniqueLookup(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:23428

◆ cuddEstimateCofactorSimple()

static int cuddEstimateCofactorSimple ( DdNode node,
int  i 
)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_CofactorEstimateSimple.]

Description [Performs the recursive step of Cudd_CofactorEstimateSimple. Returns an estimate of the number of nodes in the DD of the positive cofactor of node. Uses the least significant bit of the next field as visited flag. node is supposed to be regular; the invariant is maintained by this procedure.]

SideEffects [None]

SeeAlso []

Definition at line 23487 of file cuddInt.c.

23490 {
23491 int tval, eval;
23492 
23493 if (Cudd_IsComplement(node->next)) {
23494 return(0);
23495 }
23496 node->next = Cudd_Not(node->next);
23497 if (cuddIsConstant(node)) {
23498 return(1);
23499 }
23500 tval = cuddEstimateCofactorSimple(cuddT(node),i);
23501 if ((int) node->index == i) return(tval);
23503 return(1 + tval + eval);
23504 
23505 } /* end of cuddEstimateCofactorSimple */
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_Regular(node)
Definition: cudd.h:373
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode * next
Definition: cudd.h:267
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
static int cuddEstimateCofactorSimple(DdNode *node, int i)
Definition: cuddInt.c:23487
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625

◆ cuddExact()

int cuddExact ( DdManager table,
int  lower,
int  upper 
)

AutomaticEnd Function********************************************************************

Synopsis [Exact variable ordering algorithm.]

Description [Exact variable ordering algorithm. Finds an optimum order for the variables between lower and upper. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 6474 of file cuddInt.c.

6478 {
6479  int k, i, j;
6480  int maxBinomial, oldSubsets, newSubsets;
6481  int subsetCost;
6482  int size; /* number of variables to be reordered */
6483  int unused, nvars, level, result;
6484  int upperBound, lowerBound, cost;
6485  int roots;
6486  char *mask = NULL;
6487  DdHalfWord *symmInfo = NULL;
6488  DdHalfWord **newOrder = NULL;
6489  DdHalfWord **oldOrder = NULL;
6490  int *newCost = NULL;
6491  int *oldCost = NULL;
6492  DdHalfWord **tmpOrder;
6493  int *tmpCost;
6494  DdHalfWord *bestOrder = NULL;
6495  DdHalfWord *order;
6496 #ifdef DD_STATS
6497  int ddTotalSubsets;
6498 #endif
6499 
6500  /* Restrict the range to be reordered by excluding unused variables
6501  ** at the two ends. */
6502  while (table->subtables[lower].keys == 1 &&
6503  table->vars[table->invperm[lower]]->ref == 1 &&
6504  lower < upper)
6505  lower++;
6506  while (table->subtables[upper].keys == 1 &&
6507  table->vars[table->invperm[upper]]->ref == 1 &&
6508  lower < upper)
6509  upper--;
6510  if (lower == upper) return(1); /* trivial problem */
6511 
6512  /* Apply symmetric sifting to get a good upper bound and to extract
6513  ** symmetry information. */
6514  result = cuddSymmSiftingConv(table,lower,upper);
6515  if (result == 0) goto cuddExactOutOfMem;
6516 
6517 #ifdef DD_STATS
6518  (void) fprintf(table->out,"\n");
6519  ddTotalShuffles = 0;
6520  ddTotalSubsets = 0;
6521 #endif
6522 
6523  /* Initialization. */
6524  nvars = table->size;
6525  size = upper - lower + 1;
6526  /* Count unused variable among those to be reordered. This is only
6527  ** used to compute maxBinomial. */
6528  unused = 0;
6529  for (i = lower + 1; i < upper; i++) {
6530  if (table->subtables[i].keys == 1 &&
6531  table->vars[table->invperm[i]]->ref == 1)
6532  unused++;
6533  }
6534 
6535  /* Find the maximum number of subsets we may have to store. */
6536  maxBinomial = getMaxBinomial(size - unused);
6537  if (maxBinomial == -1) goto cuddExactOutOfMem;
6538 
6539  newOrder = getMatrix(maxBinomial, size);
6540  if (newOrder == NULL) goto cuddExactOutOfMem;
6541 
6542  newCost = ALLOC(int, maxBinomial);
6543  if (newCost == NULL) goto cuddExactOutOfMem;
6544 
6545  oldOrder = getMatrix(maxBinomial, size);
6546  if (oldOrder == NULL) goto cuddExactOutOfMem;
6547 
6548  oldCost = ALLOC(int, maxBinomial);
6549  if (oldCost == NULL) goto cuddExactOutOfMem;
6550 
6551  bestOrder = ALLOC(DdHalfWord, size);
6552  if (bestOrder == NULL) goto cuddExactOutOfMem;
6553 
6554  mask = ALLOC(char, nvars);
6555  if (mask == NULL) goto cuddExactOutOfMem;
6556 
6557  symmInfo = initSymmInfo(table, lower, upper);
6558  if (symmInfo == NULL) goto cuddExactOutOfMem;
6559 
6560  roots = ddCountRoots(table, lower, upper);
6561 
6562  /* Initialize the old order matrix for the empty subset and the best
6563  ** order to the current order. The cost for the empty subset includes
6564  ** the cost of the levels between upper and the constants. These levels
6565  ** are not going to change. Hence, we count them only once.
6566  */
6567  oldSubsets = 1;
6568  for (i = 0; i < size; i++) {
6569  oldOrder[0][i] = bestOrder[i] = (DdHalfWord) table->invperm[i+lower];
6570  }
6571  subsetCost = table->constants.keys;
6572  for (i = upper + 1; i < nvars; i++)
6573  subsetCost += getLevelKeys(table,i);
6574  oldCost[0] = subsetCost;
6575  /* The upper bound is initialized to the current size of the BDDs. */
6576  upperBound = table->keys - table->isolated;
6577 
6578  /* Now consider subsets of increasing size. */
6579  for (k = 1; k <= size; k++) {
6580 #ifdef DD_STATS
6581  (void) fprintf(table->out,"Processing subsets of size %d\n", k);
6582  fflush(table->out);
6583 #endif
6584  newSubsets = 0;
6585  level = size - k; /* offset of first bottom variable */
6586 
6587  for (i = 0; i < oldSubsets; i++) { /* for each subset of size k-1 */
6588  order = oldOrder[i];
6589  cost = oldCost[i];
6590  lowerBound = computeLB(table, order, roots, cost, lower, upper,
6591  level);
6592  if (lowerBound >= upperBound)
6593  continue;
6594  /* Impose new order. */
6595  result = ddShuffle(table, order, lower, upper);
6596  if (result == 0) goto cuddExactOutOfMem;
6597  upperBound = updateUB(table,upperBound,bestOrder,lower,upper);
6598  /* For each top bottom variable. */
6599  for (j = level; j >= 0; j--) {
6600  /* Skip unused variables. */
6601  if (table->subtables[j+lower-1].keys == 1 &&
6602  table->vars[table->invperm[j+lower-1]]->ref == 1) continue;
6603  /* Find cost under this order. */
6604  subsetCost = cost + getLevelKeys(table, lower + level);
6605  newSubsets = updateEntry(table, order, level, subsetCost,
6606  newOrder, newCost, newSubsets, mask,
6607  lower, upper);
6608  if (j == 0)
6609  break;
6610  if (checkSymmInfo(table, symmInfo, order[j-1], level) == 0)
6611  continue;
6612  pushDown(order,j-1,level);
6613  /* Impose new order. */
6614  result = ddShuffle(table, order, lower, upper);
6615  if (result == 0) goto cuddExactOutOfMem;
6616  upperBound = updateUB(table,upperBound,bestOrder,lower,upper);
6617  } /* for each bottom variable */
6618  } /* for each subset of size k */
6619 
6620  /* New orders become old orders in preparation for next iteration. */
6621  tmpOrder = oldOrder; tmpCost = oldCost;
6622  oldOrder = newOrder; oldCost = newCost;
6623  newOrder = tmpOrder; newCost = tmpCost;
6624 #ifdef DD_STATS
6625  ddTotalSubsets += newSubsets;
6626 #endif
6627  oldSubsets = newSubsets;
6628  }
6629  result = ddShuffle(table, bestOrder, lower, upper);
6630  if (result == 0) goto cuddExactOutOfMem;
6631 #ifdef DD_STATS
6632  #ifdef DD_VERBOSE
6633  (void) fprintf(table->out,"\n");
6634 #endif
6635  (void) fprintf(table->out,"#:S_EXACT %8d: total subsets\n",
6636  ddTotalSubsets);
6637  (void) fprintf(table->out,"#:H_EXACT %8d: total shuffles",
6638  ddTotalShuffles);
6639 #endif
6640 
6641  freeMatrix(newOrder);
6642  freeMatrix(oldOrder);
6643  FREE(bestOrder);
6644  FREE(oldCost);
6645  FREE(newCost);
6646  FREE(symmInfo);
6647  FREE(mask);
6648  return(1);
6649 
6650  cuddExactOutOfMem:
6651 
6652  if (newOrder != NULL) freeMatrix(newOrder);
6653  if (oldOrder != NULL) freeMatrix(oldOrder);
6654  if (bestOrder != NULL) FREE(bestOrder);
6655  if (oldCost != NULL) FREE(oldCost);
6656  if (newCost != NULL) FREE(newCost);
6657  if (symmInfo != NULL) FREE(symmInfo);
6658  if (mask != NULL) FREE(mask);
6659  table->errorCode = CUDD_MEMORY_OUT;
6660  return(0);
6661 
6662 } /* end of cuddExact */
static int getMaxBinomial(int n)
Definition: cuddInt.c:6684
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
unsigned short DdHalfWord
Definition: cudd.h:253
static int ddShuffle(DdManager *table, DdHalfWord *permutation, int lower, int upper)
Definition: cuddInt.c:6862
static DdHalfWord ** getMatrix(int rows, int cols)
Definition: cuddInt.c:6772
#define FREE(obj)
Definition: util.h:80
int size
Definition: cuddInt.h:345
static void pushDown(DdHalfWord *order, int j, int level)
Definition: cuddInt.c:7255
int cuddSymmSiftingConv(DdManager *table, int lower, int upper)
Definition: cuddInt.c:18163
static int ddCountRoots(DdManager *table, int lower, int upper)
Definition: cuddInt.c:7021
DdSubtable * subtables
Definition: cuddInt.h:349
static void freeMatrix(DdHalfWord **matrix)
Definition: cuddInt.c:6807
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static int computeLB(DdManager *table, DdHalfWord *order, int roots, int cost, int lower, int upper, int level)
Definition: cuddInt.c:7134
static int updateUB(DdManager *table, int oldBound, DdHalfWord *bestOrder, int lower, int upper)
Definition: cuddInt.c:6979
static int updateEntry(DdManager *table, DdHalfWord *order, int level, int cost, DdHalfWord **orders, int *costs, int subsets, char *mask, int lower, int upper)
Definition: cuddInt.c:7201
static int getLevelKeys(DdManager *table, int l)
Definition: cuddInt.c:6830
static int result
Definition: cuddInt.c:7466
DdNode ** vars
Definition: cuddInt.h:373
int * invperm
Definition: cuddInt.h:371
DdSubtable constants
Definition: cuddInt.h:351
int isolated
Definition: cuddInt.h:368
static int checkSymmInfo(DdManager *table, DdHalfWord *symmInfo, int index, int level)
Definition: cuddInt.c:7329
static DdHalfWord * initSymmInfo(DdManager *table, int lower, int upper)
Definition: cuddInt.c:7293
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddFreeTable()

void cuddFreeTable ( DdManager unique)

Function********************************************************************

Synopsis [Frees the resources associated to a unique table.]

Description []

SideEffects [None]

SeeAlso [cuddInitTable]

Definition at line 20050 of file cuddInt.c.

20052 {
20053 DdNodePtr *next;
20054 DdNodePtr *memlist = unique->memoryList;
20055 int i;
20056 
20057 if (unique->univ != NULL) cuddZddFreeUniv(unique);
20058 while (memlist != NULL) {
20059 next = (DdNodePtr *) memlist[0]; /* link to next block */
20060 FREE(memlist);
20061 memlist = next;
20062 }
20063 unique->nextFree = NULL;
20064 unique->memoryList = NULL;
20065 
20066 for (i = 0; i < unique->size; i++) {
20067 FREE(unique->subtables[i].nodelist);
20068 }
20069 for (i = 0; i < unique->sizeZ; i++) {
20070 FREE(unique->subtableZ[i].nodelist);
20071 }
20072 FREE(unique->constants.nodelist);
20073 FREE(unique->subtables);
20074 FREE(unique->subtableZ);
20075 FREE(unique->acache);
20076 FREE(unique->perm);
20077 FREE(unique->permZ);
20078 FREE(unique->invperm);
20079 FREE(unique->invpermZ);
20080 FREE(unique->vars);
20081 if (unique->map != NULL) FREE(unique->map);
20082 FREE(unique->stack);
20083 #ifndef DD_NO_DEATH_ROW
20084 FREE(unique->deathRow);
20085 #endif
20086 if (unique->tree != NULL) Mtr_FreeTree(unique->tree);
20087 if (unique->treeZ != NULL) Mtr_FreeTree(unique->treeZ);
20088 if (unique->linear != NULL) FREE(unique->linear);
20089 while (unique->preGCHook != NULL)
20090 Cudd_RemoveHook(unique,unique->preGCHook->f,CUDD_PRE_GC_HOOK);
20091 while (unique->postGCHook != NULL)
20093 while (unique->preReorderingHook != NULL)
20094 Cudd_RemoveHook(unique,unique->preReorderingHook->f,
20096 while (unique->postReorderingHook != NULL)
20097 Cudd_RemoveHook(unique,unique->postReorderingHook->f,
20099 FREE(unique);
20100 
20101 } /* end of cuddFreeTable */
int * map
Definition: cuddInt.h:374
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
DdHook * preReorderingHook
Definition: cuddInt.h:421
int * invpermZ
Definition: cuddInt.h:372
int size
Definition: cuddInt.h:345
void Mtr_FreeTree(MtrNode *node)
Definition: mtr.c:187
DdSubtable * subtables
Definition: cuddInt.h:349
int * permZ
Definition: cuddInt.h:370
MtrNode * tree
Definition: cuddInt.h:408
DD_HFP f
Definition: cuddInt.h:241
DdNode ** deathRow
Definition: cuddInt.h:384
DdNode ** stack
Definition: cuddInt.h:364
DdHook * postReorderingHook
Definition: cuddInt.h:422
long * linear
Definition: cuddInt.h:378
DdNode ** nodelist
Definition: cuddInt.h:311
DdNode ** memoryList
Definition: cuddInt.h:380
DdNode * nextFree
Definition: cuddInt.h:381
int sizeZ
Definition: cuddInt.h:346
DdNode ** vars
Definition: cuddInt.h:373
DdHook * postGCHook
Definition: cuddInt.h:420
MtrNode * treeZ
Definition: cuddInt.h:409
int * invperm
Definition: cuddInt.h:371
DdSubtable constants
Definition: cuddInt.h:351
int Cudd_RemoveHook(DdManager *dd, DD_HFP f, Cudd_HookType where)
Definition: cuddInt.c:1991
DdCache * acache
Definition: cuddInt.h:335
DdHook * preGCHook
Definition: cuddInt.h:419
int * perm
Definition: cuddInt.h:369
DdSubtable * subtableZ
Definition: cuddInt.h:350
void cuddZddFreeUniv(DdManager *zdd)
Definition: cuddInt.c:10717
DdNode ** univ
Definition: cuddInt.h:375

◆ cuddGa()

int cuddGa ( DdManager table,
int  lower,
int  upper 
)

AutomaticEnd Function********************************************************************

Synopsis [Genetic algorithm for DD reordering.]

Description [Genetic algorithm for DD reordering. The two children of a crossover will be stored in storedd[popsize] and storedd[popsize+1] — the last two slots in the storedd array. (This will make comparisons and replacement easy.) Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 7533 of file cuddInt.c.

7537 {
7538  int i,n,m; /* dummy/loop vars */
7539  int index;
7540 #ifdef DD_STATS
7541  double average_fitness;
7542 #endif
7543  int small; /* index of smallest DD in population */
7544 
7545  /* Do an initial sifting to produce at least one reasonable individual. */
7546  if (!cuddSifting(table,lower,upper)) return(0);
7547 
7548  /* Get the initial values. */
7549  numvars = upper - lower + 1; /* number of variables to be reordered */
7550  if (table->populationSize == 0) {
7551  popsize = 3 * numvars; /* population size is 3 times # of vars */
7552  if (popsize > 120) {
7553  popsize = 120; /* Maximum population size is 120 */
7554  }
7555  } else {
7556  popsize = table->populationSize; /* user specified value */
7557  }
7558  if (popsize < 4) popsize = 4; /* enforce minimum population size */
7559 
7560  /* Allocate population table. */
7561  storedd = ALLOC(int,(popsize+2)*(numvars+1));
7562  if (storedd == NULL) {
7563  table->errorCode = CUDD_MEMORY_OUT;
7564  return(0);
7565  }
7566 
7567  /* Initialize the computed table. This table is made up of two data
7568  ** structures: A hash table with the key given by the order, which says
7569  ** if a given order is present in the population; and the repeat
7570  ** vector, which says how many copies of a given order are stored in
7571  ** the population table. If there are multiple copies of an order, only
7572  ** one has a repeat count greater than 1. This copy is the one pointed
7573  ** by the computed table.
7574  */
7575  repeat = ALLOC(int,popsize);
7576  if (repeat == NULL) {
7577  table->errorCode = CUDD_MEMORY_OUT;
7578  FREE(storedd);
7579  return(0);
7580  }
7581  for (i = 0; i < popsize; i++) {
7582  repeat[i] = 0;
7583  }
7585  if (computed == NULL) {
7586  table->errorCode = CUDD_MEMORY_OUT;
7587  FREE(storedd);
7588  FREE(repeat);
7589  return(0);
7590  }
7591 
7592  /* Copy the current DD and its size to the population table. */
7593  for (i = 0; i < numvars; i++) {
7594  STOREDD(0,i) = table->invperm[i+lower]; /* order of initial DD */
7595  }
7596  STOREDD(0,numvars) = table->keys - table->isolated; /* size of initial DD */
7597 
7598  /* Store the initial order in the computed table. */
7599  if (st_insert(computed,(char *)storedd,(char *) 0) == ST_OUT_OF_MEM) {
7600  FREE(storedd);
7601  FREE(repeat);
7603  return(0);
7604  }
7605  repeat[0]++;
7606 
7607  /* Insert the reverse order as second element of the population. */
7608  for (i = 0; i < numvars; i++) {
7609  STOREDD(1,numvars-1-i) = table->invperm[i+lower]; /* reverse order */
7610  }
7611 
7612  /* Now create the random orders. make_random fills the population
7613  ** table with random permutations. The successive loop builds and sifts
7614  ** the DDs for the reverse order and each random permutation, and stores
7615  ** the results in the computed table.
7616  */
7617  if (!make_random(table,lower)) {
7618  table->errorCode = CUDD_MEMORY_OUT;
7619  FREE(storedd);
7620  FREE(repeat);
7622  return(0);
7623  }
7624  for (i = 1; i < popsize; i++) {
7625  result = build_dd(table,i,lower,upper); /* build and sift order */
7626  if (!result) {
7627  FREE(storedd);
7628  FREE(repeat);
7630  return(0);
7631  }
7632  if (st_lookup_int(computed,(char *)&STOREDD(i,0),&index)) {
7633  repeat[index]++;
7634  } else {
7635  if (st_insert(computed,(char *)&STOREDD(i,0),(char *)(long)i) ==
7636  ST_OUT_OF_MEM) {
7637  FREE(storedd);
7638  FREE(repeat);
7640  return(0);
7641  }
7642  repeat[i]++;
7643  }
7644  }
7645 
7646 #if 0
7647  #ifdef DD_STATS
7648  /* Print the initial population. */
7649  (void) fprintf(table->out,"Initial population after sifting\n");
7650  for (m = 0; m < popsize; m++) {
7651  for (i = 0; i < numvars; i++) {
7652  (void) fprintf(table->out," %2d",STOREDD(m,i));
7653  }
7654  (void) fprintf(table->out," : %3d (%d)\n",
7655  STOREDD(m,numvars),repeat[m]);
7656  }
7657 #endif
7658 #endif
7659 
7660  small = find_best();
7661 #ifdef DD_STATS
7662  average_fitness = find_average_fitness();
7663  (void) fprintf(table->out,"\nInitial population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness);
7664 #endif
7665 
7666  /* Decide how many crossovers should be tried. */
7667  if (table->numberXovers == 0) {
7668  cross = 3*numvars;
7669  if (cross > 60) { /* do a maximum of 50 crossovers */
7670  cross = 60;
7671  }
7672  } else {
7673  cross = table->numberXovers; /* use user specified value */
7674  }
7675  if (cross >= popsize) {
7676  cross = popsize;
7677  }
7678 
7679  /* Perform the crossovers to get the best order. */
7680  for (m = 0; m < cross; m++) {
7681  if (!PMX(table->size)) { /* perform one crossover */
7682  table->errorCode = CUDD_MEMORY_OUT;
7683  FREE(storedd);
7684  FREE(repeat);
7686  return(0);
7687  }
7688  /* The offsprings are left in the last two entries of the
7689  ** population table. These are now considered in turn.
7690  */
7691  for (i = popsize; i <= popsize+1; i++) {
7692  result = build_dd(table,i,lower,upper); /* build and sift child */
7693  if (!result) {
7694  FREE(storedd);
7695  FREE(repeat);
7697  return(0);
7698  }
7699  large = largest(); /* find the largest DD in population */
7700 
7701  /* If the new child is smaller than the largest DD in the current
7702  ** population, enter it into the population in place of the
7703  ** largest DD.
7704  */
7705  if (STOREDD(i,numvars) < STOREDD(large,numvars)) {
7706  /* Look up the largest DD in the computed table.
7707  ** Decrease its repetition count. If the repetition count
7708  ** goes to 0, remove the largest DD from the computed table.
7709  */
7710  result = st_lookup_int(computed,(char *)&STOREDD(large,0),
7711  &index);
7712  if (!result) {
7713  FREE(storedd);
7714  FREE(repeat);
7716  return(0);
7717  }
7718  repeat[index]--;
7719  if (repeat[index] == 0) {
7720  int *pointer = &STOREDD(index,0);
7721  result = st_delete(computed, &pointer, NULL);
7722  if (!result) {
7723  FREE(storedd);
7724  FREE(repeat);
7726  return(0);
7727  }
7728  }
7729  /* Copy the new individual to the entry of the
7730  ** population table just made available and update the
7731  ** computed table.
7732  */
7733  for (n = 0; n <= numvars; n++) {
7734  STOREDD(large,n) = STOREDD(i,n);
7735  }
7736  if (st_lookup_int(computed,(char *)&STOREDD(large,0),
7737  &index)) {
7738  repeat[index]++;
7739  } else {
7740  if (st_insert(computed,(char *)&STOREDD(large,0),
7741  (char *)(long)large) == ST_OUT_OF_MEM) {
7742  FREE(storedd);
7743  FREE(repeat);
7745  return(0);
7746  }
7747  repeat[large]++;
7748  }
7749  }
7750  }
7751  }
7752 
7753  /* Find the smallest DD in the population and build it;
7754  ** that will be the result.
7755  */
7756  small = find_best();
7757 
7758  /* Print stats on the final population. */
7759 #ifdef DD_STATS
7760  average_fitness = find_average_fitness();
7761  (void) fprintf(table->out,"\nFinal population: best fitness = %d, average fitness %8.3f",STOREDD(small,numvars),average_fitness);
7762 #endif
7763 
7764  /* Clean up, build the result DD, and return. */
7766  computed = NULL;
7767  result = build_dd(table,small,lower,upper);
7768  FREE(storedd);
7769  FREE(repeat);
7770  return(result);
7771 
7772 } /* end of cuddGa */
static int make_random(DdManager *table, int lower)
Definition: cuddInt.c:7793
int st_lookup_int(st_table *, void *, int *)
Definition: st.c:307
#define FREE(obj)
Definition: util.h:80
int size
Definition: cuddInt.h:345
void st_free_table(st_table *)
Definition: st.c:237
int populationSize
Definition: cuddInt.h:414
static int popsize
Definition: cuddInt.c:7451
static int largest(void)
Definition: cuddInt.c:7968
static int numvars
Definition: cuddInt.c:7452
int cuddSifting(DdManager *table, int lower, int upper)
Definition: cuddInt.c:14824
static int cross
Definition: cuddInt.c:7467
#define STOREDD(i, j)
Definition: cuddInt.c:7476
int st_insert(st_table *, void *, void *)
Definition: st.c:343
static int PMX(int maxvar)
Definition: cuddInt.c:8138
static int find_best(void)
Definition: cuddInt.c:8080
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static int array_hash(char *array, int modulus)
Definition: cuddInt.c:8018
int numberXovers
Definition: cuddInt.h:415
static st_table * computed
Definition: cuddInt.c:7462
st_table * st_init_table(ST_PFICPCP, ST_PFICPI)
Definition: st.c:148
#define ST_OUT_OF_MEM
Definition: st.h:41
static int array_compare(const char *array1, const char *array2)
Definition: cuddInt.c:8050
static int * storedd
Definition: cuddInt.c:7461
int st_delete(st_table *, void *, void *)
Definition: st.c:437
static int result
Definition: cuddInt.c:7466
static int build_dd(DdManager *table, int num, int lower, int upper)
Definition: cuddInt.c:7897
static int large
Definition: cuddInt.c:7464
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
static int * repeat
Definition: cuddInt.c:7463

◆ cuddGarbageCollect()

int cuddGarbageCollect ( DdManager unique,
int  clearCache 
)

Function********************************************************************

Synopsis [Performs garbage collection on the unique tables.]

Description [Performs garbage collection on the BDD and ZDD unique tables. If clearCache is 0, the cache is not cleared. This should only be specified if the cache has been cleared right before calling cuddGarbageCollect. (As in the case of dynamic reordering.) Returns the total number of deleted nodes.]

SideEffects [None]

SeeAlso []

Definition at line 20120 of file cuddInt.c.

20123 {
20124 DdHook *hook;
20125 DdCache *cache = unique->cache;
20126 DdNode *sentinel = &(unique->sentinel);
20127 DdNodePtr *nodelist;
20128 int i, j, deleted, totalDeleted, totalDeletedZ;
20129 DdCache *c;
20130 DdNode *node,*next;
20131 DdNodePtr *lastP;
20132 int slots;
20133 unsigned long localTime;
20134 #ifndef DD_UNSORTED_FREE_LIST
20135 #ifdef DD_RED_BLACK_FREE_LIST
20136 DdNodePtr tree;
20137 #else
20138 DdNodePtr *memListTrav, *nxtNode;
20139 DdNode *downTrav, *sentry;
20140 int k;
20141 #endif
20142 #endif
20143 
20144 #ifndef DD_NO_DEATH_ROW
20145 cuddClearDeathRow(unique);
20146 #endif
20147 
20148 hook = unique->preGCHook;
20149 while (hook != NULL) {
20150 int res = (hook->f)(unique,"DD",NULL);
20151 if (res == 0) return(0);
20152 hook = hook->next;
20153 }
20154 
20155 if (unique->dead + unique->deadZ == 0) {
20156 hook = unique->postGCHook;
20157 while (hook != NULL) {
20158 int res = (hook->f)(unique,"DD",NULL);
20159 if (res == 0) return(0);
20160 hook = hook->next;
20161 }
20162 return(0);
20163 }
20164 
20165 /* If many nodes are being reclaimed, we want to resize the tables
20166 ** more aggressively, to reduce the frequency of garbage collection.
20167 */
20168 if (clearCache && unique->gcFrac == DD_GC_FRAC_LO &&
20169 unique->slots <= unique->looseUpTo && unique->stash != NULL) {
20170 unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots);
20171 #ifdef DD_VERBOSE
20172 (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_HI);
20173 (void) fprintf(unique->err,"minDead = %d\n", unique->minDead);
20174 #endif
20175 unique->gcFrac = DD_GC_FRAC_HI;
20176 return(0);
20177 }
20178 
20179 localTime = util_cpu_time();
20180 
20181 unique->garbageCollections++;
20182 #ifdef DD_VERBOSE
20183 (void) fprintf(unique->err,
20184 "garbage collecting (%d dead BDD nodes out of %d, min %d)...",
20185 unique->dead, unique->keys, unique->minDead);
20186 (void) fprintf(unique->err,
20187 " (%d dead ZDD nodes out of %d)...",
20188 unique->deadZ, unique->keysZ);
20189 #endif
20190 
20191 /* Remove references to garbage collected nodes from the cache. */
20192 if (clearCache) {
20193 slots = unique->cacheSlots;
20194 for (i = 0; i < slots; i++) {
20195 c = &cache[i];
20196 if (c->data != NULL) {
20197 if (cuddClean(c->f)->ref == 0 ||
20198 cuddClean(c->g)->ref == 0 ||
20199 (((ptruint)c->f & 0x2) && Cudd_Regular(c->h)->ref == 0) ||
20200 (c->data != DD_NON_CONSTANT &&
20201 Cudd_Regular(c->data)->ref == 0)) {
20202 c->data = NULL;
20203 unique->cachedeletions++;
20204 }
20205 }
20206 }
20207 cuddLocalCacheClearDead(unique);
20208 }
20209 
20210 /* Now return dead nodes to free list. Count them for sanity check. */
20211 totalDeleted = 0;
20212 #ifndef DD_UNSORTED_FREE_LIST
20213 #ifdef DD_RED_BLACK_FREE_LIST
20214 tree = NULL;
20215 #endif
20216 #endif
20217 
20218 for (i = 0; i < unique->size; i++) {
20219 if (unique->subtables[i].dead == 0) continue;
20220 nodelist = unique->subtables[i].nodelist;
20221 
20222 deleted = 0;
20223 slots = unique->subtables[i].slots;
20224 for (j = 0; j < slots; j++) {
20225 lastP = &(nodelist[j]);
20226 node = *lastP;
20227 while (node != sentinel) {
20228 next = node->next;
20229 if (node->ref == 0) {
20230 deleted++;
20231 #ifndef DD_UNSORTED_FREE_LIST
20232 #ifdef DD_RED_BLACK_FREE_LIST
20233 cuddOrderedInsert(&tree,node);
20234 #endif
20235 #else
20236 cuddDeallocNode(unique,node);
20237 #endif
20238 } else {
20239 *lastP = node;
20240 lastP = &(node->next);
20241 }
20242 node = next;
20243 }
20244 *lastP = sentinel;
20245 }
20246 if ((unsigned) deleted != unique->subtables[i].dead) {
20247 ddReportRefMess(unique, i, "cuddGarbageCollect");
20248 }
20249 totalDeleted += deleted;
20250 unique->subtables[i].keys -= deleted;
20251 unique->subtables[i].dead = 0;
20252 }
20253 if (unique->constants.dead != 0) {
20254 nodelist = unique->constants.nodelist;
20255 deleted = 0;
20256 slots = unique->constants.slots;
20257 for (j = 0; j < slots; j++) {
20258 lastP = &(nodelist[j]);
20259 node = *lastP;
20260 while (node != NULL) {
20261 next = node->next;
20262 if (node->ref == 0) {
20263 deleted++;
20264 #ifndef DD_UNSORTED_FREE_LIST
20265 #ifdef DD_RED_BLACK_FREE_LIST
20266 cuddOrderedInsert(&tree,node);
20267 #endif
20268 #else
20269 cuddDeallocNode(unique,node);
20270 #endif
20271 } else {
20272 *lastP = node;
20273 lastP = &(node->next);
20274 }
20275 node = next;
20276 }
20277 *lastP = NULL;
20278 }
20279 if ((unsigned) deleted != unique->constants.dead) {
20280 ddReportRefMess(unique, CUDD_CONST_INDEX, "cuddGarbageCollect");
20281 }
20282 totalDeleted += deleted;
20283 unique->constants.keys -= deleted;
20284 unique->constants.dead = 0;
20285 }
20286 if ((unsigned) totalDeleted != unique->dead) {
20287 ddReportRefMess(unique, -1, "cuddGarbageCollect");
20288 }
20289 unique->keys -= totalDeleted;
20290 unique->dead = 0;
20291 #ifdef DD_STATS
20292 unique->nodesFreed += (double) totalDeleted;
20293 #endif
20294 
20295 totalDeletedZ = 0;
20296 
20297 for (i = 0; i < unique->sizeZ; i++) {
20298 if (unique->subtableZ[i].dead == 0) continue;
20299 nodelist = unique->subtableZ[i].nodelist;
20300 
20301 deleted = 0;
20302 slots = unique->subtableZ[i].slots;
20303 for (j = 0; j < slots; j++) {
20304 lastP = &(nodelist[j]);
20305 node = *lastP;
20306 while (node != NULL) {
20307 next = node->next;
20308 if (node->ref == 0) {
20309 deleted++;
20310 #ifndef DD_UNSORTED_FREE_LIST
20311 #ifdef DD_RED_BLACK_FREE_LIST
20312 cuddOrderedInsert(&tree,node);
20313 #endif
20314 #else
20315 cuddDeallocNode(unique,node);
20316 #endif
20317 } else {
20318 *lastP = node;
20319 lastP = &(node->next);
20320 }
20321 node = next;
20322 }
20323 *lastP = NULL;
20324 }
20325 if ((unsigned) deleted != unique->subtableZ[i].dead) {
20326 ddReportRefMess(unique, i, "cuddGarbageCollect");
20327 }
20328 totalDeletedZ += deleted;
20329 unique->subtableZ[i].keys -= deleted;
20330 unique->subtableZ[i].dead = 0;
20331 }
20332 
20333 /* No need to examine the constant table for ZDDs.
20334 ** If we did we should be careful not to count whatever dead
20335 ** nodes we found there among the dead ZDD nodes. */
20336 if ((unsigned) totalDeletedZ != unique->deadZ) {
20337 ddReportRefMess(unique, -1, "cuddGarbageCollect");
20338 }
20339 unique->keysZ -= totalDeletedZ;
20340 unique->deadZ = 0;
20341 #ifdef DD_STATS
20342 unique->nodesFreed += (double) totalDeletedZ;
20343 #endif
20344 
20345 
20346 #ifndef DD_UNSORTED_FREE_LIST
20347 #ifdef DD_RED_BLACK_FREE_LIST
20348 unique->nextFree = cuddOrderedThread(tree,unique->nextFree);
20349 #else
20350 memListTrav = unique->memoryList;
20351 sentry = NULL;
20352 while (memListTrav != NULL) {
20353 ptruint offset;
20354 nxtNode = (DdNodePtr *)memListTrav[0];
20355 offset = (ptruint) memListTrav & (sizeof(DdNode) - 1);
20356 memListTrav += (sizeof(DdNode) - offset) / sizeof(DdNodePtr);
20357 downTrav = (DdNode *)memListTrav;
20358 k = 0;
20359 do {
20360 if (downTrav[k].ref == 0) {
20361 if (sentry == NULL) {
20362 unique->nextFree = sentry = &downTrav[k];
20363 } else {
20364 /* First hook sentry->next to the dead node and then
20365 ** reassign sentry to the dead node. */
20366 sentry = (sentry->next = &downTrav[k]);
20367 }
20368 }
20369 } while (++k < DD_MEM_CHUNK);
20370 memListTrav = nxtNode;
20371 }
20372 sentry->next = NULL;
20373 #endif
20374 #endif
20375 
20376 unique->GCTime += util_cpu_time() - localTime;
20377 
20378 hook = unique->postGCHook;
20379 while (hook != NULL) {
20380 int res = (hook->f)(unique,"DD",NULL);
20381 if (res == 0) return(0);
20382 hook = hook->next;
20383 }
20384 
20385 #ifdef DD_VERBOSE
20386 (void) fprintf(unique->err," done\n");
20387 #endif
20388 
20389 return(totalDeleted+totalDeletedZ);
20390 
20391 } /* end of cuddGarbageCollect */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
DdNode * f
Definition: cuddInt.h:302
Definition: cudd.h:264
unsigned int deadZ
Definition: cuddInt.h:356
DdNode * data
Definition: cuddInt.h:304
int size
Definition: cuddInt.h:345
double gcFrac
Definition: cuddInt.h:359
unsigned int slots
Definition: cuddInt.h:352
ptruint h
Definition: cuddInt.h:303
#define Cudd_Regular(node)
Definition: cudd.h:373
FILE * err
Definition: cuddInt.h:424
DdNode * g
Definition: cuddInt.h:302
int garbageCollections
Definition: cuddInt.h:432
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode * DdNodePtr
Definition: cuddInt.h:253
DD_HFP f
Definition: cuddInt.h:241
struct DdNode DdNode
Definition: cudd.h:256
#define DD_GC_FRAC_HI
Definition: cuddInt.h:135
unsigned int dead
Definition: cuddInt.h:355
unsigned int cacheSlots
Definition: cuddInt.h:337
DdNode sentinel
Definition: cuddInt.h:328
char * stash
Definition: cuddInt.h:382
unsigned int keys
Definition: cuddInt.h:353
unsigned int dead
Definition: cuddInt.h:316
DdCache * cache
Definition: cuddInt.h:336
DdNode * next
Definition: cudd.h:267
#define DD_GC_FRAC_LO
Definition: cuddInt.h:134
#define CUDD_CONST_INDEX
Definition: cudd.h:107
DdNode ** nodelist
Definition: cuddInt.h:311
void cuddLocalCacheClearDead(DdManager *manager)
Definition: cuddInt.c:11362
long util_cpu_time(void)
Definition: util.c:34
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:520
unsigned long GCTime
Definition: cuddInt.h:433
DdNode ** memoryList
Definition: cuddInt.h:380
unsigned int ptruint
Definition: cuddInt.h:250
DdNode * nextFree
Definition: cuddInt.h:381
struct DdHook * next
Definition: cuddInt.h:242
int sizeZ
Definition: cuddInt.h:346
unsigned int looseUpTo
Definition: cuddInt.h:361
unsigned int slots
Definition: cuddInt.h:313
DdHook * postGCHook
Definition: cuddInt.h:420
static void ddReportRefMess(DdManager *unique, int i, const char *caller)
Definition: cuddInt.c:21976
#define cuddClean(p)
Definition: cuddInt.h:757
void cuddClearDeathRow(DdManager *table)
Definition: cuddInt.c:14365
DdSubtable constants
Definition: cuddInt.h:351
double cachedeletions
Definition: cuddInt.h:440
#define DD_MEM_CHUNK
Definition: cuddInt.h:105
unsigned int keysZ
Definition: cuddInt.h:354
DdHook * preGCHook
Definition: cuddInt.h:419
unsigned int minDead
Definition: cuddInt.h:358
DdSubtable * subtableZ
Definition: cuddInt.h:350
#define DD_NON_CONSTANT
Definition: cuddInt.h:124

◆ cuddGetBranches()

void cuddGetBranches ( DdNode g,
DdNode **  g1,
DdNode **  g0 
)

Function********************************************************************

Synopsis [Computes the children of g.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 6196 of file cuddInt.c.

6200 {
6201  DdNode *G = Cudd_Regular(g);
6202 
6203  *g1 = cuddT(G);
6204  *g0 = cuddE(G);
6205  if (Cudd_IsComplement(g)) {
6206  *g1 = Cudd_Not(*g1);
6207  *g0 = Cudd_Not(*g0);
6208  }
6209 
6210 } /* end of cuddGetBranches */
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_Regular(node)
Definition: cudd.h:373
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddE(node)
Definition: cuddInt.h:625

◆ cuddHashTableAlloc()

static DD_INLINE DdHashItem * cuddHashTableAlloc ( DdHashTable hash)
static

Function********************************************************************

Synopsis [Fast storage allocation for items in a hash table.]

Description [Fast storage allocation for items in a hash table. The first 4 bytes of a chunk contain a pointer to the next block; the rest contains DD_MEM_CHUNK spaces for hash items. Returns a pointer to a new item if successful; NULL is memory is full.]

SideEffects [None]

SeeAlso [cuddAllocNode cuddDynamicAllocNode]

Definition at line 12494 of file cuddInt.c.

12496 {
12497 int i;
12498 unsigned int itemsize = hash->itemsize;
12499 extern DD_OOMFP MMoutOfMemory;
12500 DD_OOMFP saveHandler;
12501 DdHashItem **mem, *thisOne, *next, *item;
12502 
12503 if (hash->nextFree == NULL) {
12504 saveHandler = MMoutOfMemory;
12505 MMoutOfMemory = Cudd_OutOfMem;
12506 mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize);
12507 MMoutOfMemory = saveHandler;
12508 if (mem == NULL) {
12509 if (hash->manager->stash != NULL) {
12510 FREE(hash->manager->stash);
12511 hash->manager->stash = NULL;
12512 /* Inhibit resizing of tables. */
12513 hash->manager->maxCacheHard = hash->manager->cacheSlots - 1;
12514 hash->manager->cacheSlack = - (int) (hash->manager->cacheSlots + 1);
12515 for (i = 0; i < hash->manager->size; i++) {
12516 hash->manager->subtables[i].maxKeys <<= 2;
12517 }
12518 hash->manager->gcFrac = 0.2;
12519 hash->manager->minDead =
12520 (unsigned) (0.2 * (double) hash->manager->slots);
12521 mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize);
12522 }
12523 if (mem == NULL) {
12524 (*MMoutOfMemory)((long)((DD_MEM_CHUNK + 1) * itemsize));
12526 return(NULL);
12527 }
12528 }
12529 
12530 mem[0] = (DdHashItem *) hash->memoryList;
12531 hash->memoryList = mem;
12532 
12533 thisOne = (DdHashItem *) ((char *) mem + itemsize);
12534 hash->nextFree = thisOne;
12535 for (i = 1; i < DD_MEM_CHUNK; i++) {
12536 next = (DdHashItem *) ((char *) thisOne + itemsize);
12537 thisOne->next = next;
12538 thisOne = next;
12539 }
12540 
12541 thisOne->next = NULL;
12542 
12543 }
12544 item = hash->nextFree;
12545 hash->nextFree = item->next;
12546 return(item);
12547 
12548 } /* end of cuddHashTableAlloc */
#define FREE(obj)
Definition: util.h:80
DdManager * manager
Definition: cuddInt.h:298
int size
Definition: cuddInt.h:345
double gcFrac
Definition: cuddInt.h:359
unsigned int maxCacheHard
Definition: cuddInt.h:343
unsigned int slots
Definition: cuddInt.h:352
struct DdHashItem * next
Definition: cuddInt.h:281
DdSubtable * subtables
Definition: cuddInt.h:349
void(* DD_OOMFP)(long)
Definition: cudd.h:300
unsigned int cacheSlots
Definition: cuddInt.h:337
char * stash
Definition: cuddInt.h:382
#define ALLOC(type, num)
Definition: util.h:76
unsigned int maxKeys
Definition: cuddInt.h:315
int cacheSlack
Definition: cuddInt.h:342
void(* MMoutOfMemory)(long)
Definition: util.c:105
unsigned int itemsize
Definition: cuddInt.h:290
DdHashItem * nextFree
Definition: cuddInt.h:292
void Cudd_OutOfMem(long size)
Definition: cuddInt.c:22982
#define DD_MEM_CHUNK
Definition: cuddInt.h:105
DdHashItem ** memoryList
Definition: cuddInt.h:293
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
unsigned int minDead
Definition: cuddInt.h:358

◆ cuddHashTableGenericInsert()

int cuddHashTableGenericInsert ( DdHashTable hash,
DdNode f,
void *  value 
)

Function********************************************************************

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key is one pointer and the value is not a DdNode pointer. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert1 cuddHashTableGenericLookup]

Definition at line 11910 of file cuddInt.c.

11914 {
11915  int result;
11916  unsigned int posn;
11917  DdHashItem *item;
11918 
11919 #ifdef DD_DEBUG
11920  assert(hash->keysize == 1);
11921 #endif
11922 
11923  if (hash->size > hash->maxsize) {
11924  result = cuddHashTableResize(hash);
11925  if (result == 0) return(0);
11926  }
11927  item = cuddHashTableAlloc(hash);
11928  if (item == NULL) return(0);
11929  hash->size++;
11930  item->value = (DdNode *) value;
11931  item->count = 0;
11932  item->key[0] = f;
11933  posn = ddLCHash1(f,hash->shift);
11934  item->next = hash->bucket[posn];
11935  hash->bucket[posn] = item;
11936 
11937  return(1);
11938 
11939 } /* end of cuddHashTableGenericInsert */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
Definition: cudd.h:264
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddInt.c:12494
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
unsigned int maxsize
Definition: cuddInt.h:297
#define ddLCHash1(f, shift)
Definition: cuddInt.c:11283
static int result
Definition: cuddInt.c:7466
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddInt.c:12392

◆ cuddHashTableGenericLookup()

void* cuddHashTableGenericLookup ( DdHashTable hash,
DdNode f 
)

Function********************************************************************

Synopsis [Looks up a key consisting of one pointer in a hash table.]

Description [Looks up a key consisting of one pointer in a hash table when the value is not a DdNode pointer. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableLookup1 cuddHashTableGenericInsert]

Definition at line 11957 of file cuddInt.c.

11960 {
11961  unsigned int posn;
11962  DdHashItem *item;
11963 
11964 #ifdef DD_DEBUG
11965  assert(hash->keysize == 1);
11966 #endif
11967 
11968  posn = ddLCHash1(f,hash->shift);
11969  item = hash->bucket[posn];
11970 
11971  while (item != NULL) {
11972  if (f == item->key[0]) {
11973  return ((void *) item->value);
11974  }
11975  item = item->next;
11976  }
11977  return(NULL);
11978 
11979 } /* end of cuddHashTableGenericLookup */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
#define assert(ex)
Definition: util.h:141
struct DdHashItem * next
Definition: cuddInt.h:281
#define ddLCHash1(f, shift)
Definition: cuddInt.c:11283
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295

◆ cuddHashTableGenericQuit()

void cuddHashTableGenericQuit ( DdHashTable hash)

Function********************************************************************

Synopsis [Shuts down a hash table.]

Description [Shuts down a hash table, when the values are not DdNode pointers.]

SideEffects [None]

SeeAlso [cuddHashTableInit]

Definition at line 11643 of file cuddInt.c.

11645 {
11646 #ifdef __osf__
11647  #pragma pointer_size save
11648 #pragma pointer_size short
11649 #endif
11650  DdHashItem **memlist, **nextmem;
11651 
11652  memlist = hash->memoryList;
11653  while (memlist != NULL) {
11654  nextmem = (DdHashItem **) memlist[0];
11655  FREE(memlist);
11656  memlist = nextmem;
11657  }
11658 
11659  FREE(hash->bucket);
11660  FREE(hash);
11661 #ifdef __osf__
11662 #pragma pointer_size restore
11663 #endif
11664 
11665  return;
11666 
11667 } /* end of cuddHashTableGenericQuit */
DdHashItem ** bucket
Definition: cuddInt.h:291
#define FREE(obj)
Definition: util.h:80
DdHashItem ** memoryList
Definition: cuddInt.h:293

◆ cuddHashTableInit()

DdHashTable* cuddHashTableInit ( DdManager manager,
unsigned int  keySize,
unsigned int  initSize 
)

Function********************************************************************

Synopsis [Initializes a hash table.]

Description [Initializes a hash table. Returns a pointer to the new table if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableQuit]

Definition at line 11548 of file cuddInt.c.

11552 {
11553  DdHashTable *hash;
11554  int logSize;
11555 
11556  hash = ALLOC(DdHashTable, 1);
11557  if (hash == NULL) {
11558  manager->errorCode = CUDD_MEMORY_OUT;
11559  return(NULL);
11560  }
11561  hash->keysize = keySize;
11562  hash->manager = manager;
11563  hash->memoryList = NULL;
11564  hash->nextFree = NULL;
11565  hash->itemsize = (keySize + 1) * sizeof(DdNode *) +
11566  sizeof(ptrint) + sizeof(DdHashItem *);
11567  /* We have to guarantee that the shift be < 32. */
11568  if (initSize < 2) initSize = 2;
11569  logSize = cuddComputeFloorLog2(initSize);
11570  hash->numBuckets = 1 << logSize;
11571  hash->shift = sizeof(int) * 8 - logSize;
11572  hash->bucket = ALLOC(DdHashItem *, hash->numBuckets);
11573  if (hash->bucket == NULL) {
11574  manager->errorCode = CUDD_MEMORY_OUT;
11575  FREE(hash);
11576  return(NULL);
11577  }
11578  memset(hash->bucket, 0, hash->numBuckets * sizeof(DdHashItem *));
11579  hash->size = 0;
11581  return(hash);
11582 
11583 } /* end of cuddHashTableInit */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
int ptrint
Definition: cuddInt.h:249
#define DD_MAX_HASHTABLE_DENSITY
Definition: cuddInt.c:11244
unsigned int size
Definition: cuddInt.h:296
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
DdManager * manager
Definition: cuddInt.h:298
char * memset()
#define ALLOC(type, num)
Definition: util.h:76
unsigned int numBuckets
Definition: cuddInt.h:294
unsigned int maxsize
Definition: cuddInt.h:297
unsigned int itemsize
Definition: cuddInt.h:290
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddInt.c:5102
DdHashItem * nextFree
Definition: cuddInt.h:292
int shift
Definition: cuddInt.h:295
DdHashItem ** memoryList
Definition: cuddInt.h:293
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddHashTableInsert()

int cuddHashTableInsert ( DdHashTable hash,
DdNodePtr key,
DdNode value,
ptrint  count 
)

Function********************************************************************

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key has more than three pointers. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [[cuddHashTableInsert1 cuddHashTableInsert2 cuddHashTableInsert3 cuddHashTableLookup]

Definition at line 11684 of file cuddInt.c.

11689 {
11690  int result;
11691  unsigned int posn;
11692  DdHashItem *item;
11693  unsigned int i;
11694 
11695 #ifdef DD_DEBUG
11696  assert(hash->keysize > 3);
11697 #endif
11698 
11699  if (hash->size > hash->maxsize) {
11700  result = cuddHashTableResize(hash);
11701  if (result == 0) return(0);
11702  }
11703  item = cuddHashTableAlloc(hash);
11704  if (item == NULL) return(0);
11705  hash->size++;
11706  item->value = value;
11707  cuddRef(value);
11708  item->count = count;
11709  for (i = 0; i < hash->keysize; i++) {
11710  item->key[i] = key[i];
11711  }
11712  posn = ddLCHash(key,hash->keysize,hash->shift);
11713  item->next = hash->bucket[posn];
11714  hash->bucket[posn] = item;
11715 
11716  return(1);
11717 
11718 } /* end of cuddHashTableInsert */
unsigned int keysize
Definition: cuddInt.h:289
#define cuddRef(n)
Definition: cuddInt.h:557
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddInt.c:12494
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddInt.c:12304
unsigned int maxsize
Definition: cuddInt.h:297
static int result
Definition: cuddInt.c:7466
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddInt.c:12392

◆ cuddHashTableInsert1()

int cuddHashTableInsert1 ( DdHashTable hash,
DdNode f,
DdNode value,
ptrint  count 
)

Function********************************************************************

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key is one pointer. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert cuddHashTableInsert2 cuddHashTableInsert3 cuddHashTableLookup1]

Definition at line 11803 of file cuddInt.c.

11808 {
11809  int result;
11810  unsigned int posn;
11811  DdHashItem *item;
11812 
11813 #ifdef DD_DEBUG
11814  assert(hash->keysize == 1);
11815 #endif
11816 
11817  if (hash->size > hash->maxsize) {
11818  result = cuddHashTableResize(hash);
11819  if (result == 0) return(0);
11820  }
11821  item = cuddHashTableAlloc(hash);
11822  if (item == NULL) return(0);
11823  hash->size++;
11824  item->value = value;
11825  cuddRef(value);
11826  item->count = count;
11827  item->key[0] = f;
11828  posn = ddLCHash1(f,hash->shift);
11829  item->next = hash->bucket[posn];
11830  hash->bucket[posn] = item;
11831 
11832  return(1);
11833 
11834 } /* end of cuddHashTableInsert1 */
unsigned int keysize
Definition: cuddInt.h:289
#define cuddRef(n)
Definition: cuddInt.h:557
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddInt.c:12494
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
unsigned int maxsize
Definition: cuddInt.h:297
#define ddLCHash1(f, shift)
Definition: cuddInt.c:11283
static int result
Definition: cuddInt.c:7466
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddInt.c:12392

◆ cuddHashTableInsert2()

int cuddHashTableInsert2 ( DdHashTable hash,
DdNode f,
DdNode g,
DdNode value,
ptrint  count 
)

Function********************************************************************

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key is composed of two pointers. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert3 cuddHashTableLookup2]

Definition at line 11996 of file cuddInt.c.

12002 {
12003  int result;
12004  unsigned int posn;
12005  DdHashItem *item;
12006 
12007 #ifdef DD_DEBUG
12008  assert(hash->keysize == 2);
12009 #endif
12010 
12011  if (hash->size > hash->maxsize) {
12012  result = cuddHashTableResize(hash);
12013  if (result == 0) return(0);
12014  }
12015  item = cuddHashTableAlloc(hash);
12016  if (item == NULL) return(0);
12017  hash->size++;
12018  item->value = value;
12019  cuddRef(value);
12020  item->count = count;
12021  item->key[0] = f;
12022  item->key[1] = g;
12023  posn = ddLCHash2(f,g,hash->shift);
12024  item->next = hash->bucket[posn];
12025  hash->bucket[posn] = item;
12026 
12027  return(1);
12028 
12029 } /* end of cuddHashTableInsert2 */
unsigned int keysize
Definition: cuddInt.h:289
#define cuddRef(n)
Definition: cuddInt.h:557
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddInt.c:12494
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
unsigned int maxsize
Definition: cuddInt.h:297
static int result
Definition: cuddInt.c:7466
DdNode * key[1]
Definition: cuddInt.h:284
#define ddLCHash2(f, g, shift)
Definition: cuddInt.c:11304
int shift
Definition: cuddInt.h:295
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddInt.c:12392

◆ cuddHashTableInsert3()

int cuddHashTableInsert3 ( DdHashTable hash,
DdNode f,
DdNode g,
DdNode h,
DdNode value,
ptrint  count 
)

Function********************************************************************

Synopsis [Inserts an item in a hash table.]

Description [Inserts an item in a hash table when the key is composed of three pointers. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert cuddHashTableInsert1 cuddHashTableInsert2 cuddHashTableLookup3]

Definition at line 12106 of file cuddInt.c.

12113 {
12114  int result;
12115  unsigned int posn;
12116  DdHashItem *item;
12117 
12118 #ifdef DD_DEBUG
12119  assert(hash->keysize == 3);
12120 #endif
12121 
12122  if (hash->size > hash->maxsize) {
12123  result = cuddHashTableResize(hash);
12124  if (result == 0) return(0);
12125  }
12126  item = cuddHashTableAlloc(hash);
12127  if (item == NULL) return(0);
12128  hash->size++;
12129  item->value = value;
12130  cuddRef(value);
12131  item->count = count;
12132  item->key[0] = f;
12133  item->key[1] = g;
12134  item->key[2] = h;
12135  posn = ddLCHash3(f,g,h,hash->shift);
12136  item->next = hash->bucket[posn];
12137  hash->bucket[posn] = item;
12138 
12139  return(1);
12140 
12141 } /* end of cuddHashTableInsert3 */
unsigned int keysize
Definition: cuddInt.h:289
#define cuddRef(n)
Definition: cuddInt.h:557
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddInt.c:12494
#define ddLCHash3(f, g, h, shift)
Definition: cuddInt.c:11320
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
unsigned int maxsize
Definition: cuddInt.h:297
static int result
Definition: cuddInt.c:7466
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddInt.c:12392

◆ cuddHashTableLookup()

DdNode* cuddHashTableLookup ( DdHashTable hash,
DdNodePtr key 
)

Function********************************************************************

Synopsis [Looks up a key in a hash table.]

Description [Looks up a key consisting of more than three pointers in a hash table. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the value of the entry is dereferenced, and the entry is returned to the free list.]

SideEffects [None]

SeeAlso [cuddHashTableLookup1 cuddHashTableLookup2 cuddHashTableLookup3 cuddHashTableInsert]

Definition at line 11739 of file cuddInt.c.

11742 {
11743  unsigned int posn;
11744  DdHashItem *item, *prev;
11745  unsigned int i, keysize;
11746 
11747 #ifdef DD_DEBUG
11748  assert(hash->keysize > 3);
11749 #endif
11750 
11751  posn = ddLCHash(key,hash->keysize,hash->shift);
11752  item = hash->bucket[posn];
11753  prev = NULL;
11754 
11755  keysize = hash->keysize;
11756  while (item != NULL) {
11757  DdNodePtr *key2 = item->key;
11758  int equal = 1;
11759  for (i = 0; i < keysize; i++) {
11760  if (key[i] != key2[i]) {
11761  equal = 0;
11762  break;
11763  }
11764  }
11765  if (equal) {
11766  DdNode *value = item->value;
11767  cuddSatDec(item->count);
11768  if (item->count == 0) {
11769  cuddDeref(value);
11770  if (prev == NULL) {
11771  hash->bucket[posn] = item->next;
11772  } else {
11773  prev->next = item->next;
11774  }
11775  item->next = hash->nextFree;
11776  hash->nextFree = item;
11777  hash->size--;
11778  }
11779  return(value);
11780  }
11781  prev = item;
11782  item = item->next;
11783  }
11784  return(NULL);
11785 
11786 } /* end of cuddHashTableLookup */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddInt.c:12304
DdHashItem * nextFree
Definition: cuddInt.h:292
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295

◆ cuddHashTableLookup1()

DdNode* cuddHashTableLookup1 ( DdHashTable hash,
DdNode f 
)

Function********************************************************************

Synopsis [Looks up a key consisting of one pointer in a hash table.]

Description [Looks up a key consisting of one pointer in a hash table. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the value of the entry is dereferenced, and the entry is returned to the free list.]

SideEffects [None]

SeeAlso [cuddHashTableLookup cuddHashTableLookup2 cuddHashTableLookup3 cuddHashTableInsert1]

Definition at line 11855 of file cuddInt.c.

11858 {
11859  unsigned int posn;
11860  DdHashItem *item, *prev;
11861 
11862 #ifdef DD_DEBUG
11863  assert(hash->keysize == 1);
11864 #endif
11865 
11866  posn = ddLCHash1(f,hash->shift);
11867  item = hash->bucket[posn];
11868  prev = NULL;
11869 
11870  while (item != NULL) {
11871  DdNodePtr *key = item->key;
11872  if (f == key[0]) {
11873  DdNode *value = item->value;
11874  cuddSatDec(item->count);
11875  if (item->count == 0) {
11876  cuddDeref(value);
11877  if (prev == NULL) {
11878  hash->bucket[posn] = item->next;
11879  } else {
11880  prev->next = item->next;
11881  }
11882  item->next = hash->nextFree;
11883  hash->nextFree = item;
11884  hash->size--;
11885  }
11886  return(value);
11887  }
11888  prev = item;
11889  item = item->next;
11890  }
11891  return(NULL);
11892 
11893 } /* end of cuddHashTableLookup1 */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
#define ddLCHash1(f, shift)
Definition: cuddInt.c:11283
DdHashItem * nextFree
Definition: cuddInt.h:292
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295

◆ cuddHashTableLookup2()

DdNode* cuddHashTableLookup2 ( DdHashTable hash,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Looks up a key consisting of two pointers in a hash table.]

Description [Looks up a key consisting of two pointer in a hash table. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the value of the entry is dereferenced, and the entry is returned to the free list.]

SideEffects [None]

SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup3 cuddHashTableInsert2]

Definition at line 12050 of file cuddInt.c.

12054 {
12055  unsigned int posn;
12056  DdHashItem *item, *prev;
12057 
12058 #ifdef DD_DEBUG
12059  assert(hash->keysize == 2);
12060 #endif
12061 
12062  posn = ddLCHash2(f,g,hash->shift);
12063  item = hash->bucket[posn];
12064  prev = NULL;
12065 
12066  while (item != NULL) {
12067  DdNodePtr *key = item->key;
12068  if ((f == key[0]) && (g == key[1])) {
12069  DdNode *value = item->value;
12070  cuddSatDec(item->count);
12071  if (item->count == 0) {
12072  cuddDeref(value);
12073  if (prev == NULL) {
12074  hash->bucket[posn] = item->next;
12075  } else {
12076  prev->next = item->next;
12077  }
12078  item->next = hash->nextFree;
12079  hash->nextFree = item;
12080  hash->size--;
12081  }
12082  return(value);
12083  }
12084  prev = item;
12085  item = item->next;
12086  }
12087  return(NULL);
12088 
12089 } /* end of cuddHashTableLookup2 */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
DdHashItem * nextFree
Definition: cuddInt.h:292
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdNode * key[1]
Definition: cuddInt.h:284
#define ddLCHash2(f, g, shift)
Definition: cuddInt.c:11304
int shift
Definition: cuddInt.h:295

◆ cuddHashTableLookup3()

DdNode* cuddHashTableLookup3 ( DdHashTable hash,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Looks up a key consisting of three pointers in a hash table.]

Description [Looks up a key consisting of three pointers in a hash table. Returns the value associated to the key if there is an entry for the given key in the table; NULL otherwise. If the entry is present, its reference counter is decremented if not saturated. If the counter reaches 0, the value of the entry is dereferenced, and the entry is returned to the free list.]

SideEffects [None]

SeeAlso [cuddHashTableLookup cuddHashTableLookup1 cuddHashTableLookup2 cuddHashTableInsert3]

Definition at line 12162 of file cuddInt.c.

12167 {
12168  unsigned int posn;
12169  DdHashItem *item, *prev;
12170 
12171 #ifdef DD_DEBUG
12172  assert(hash->keysize == 3);
12173 #endif
12174 
12175  posn = ddLCHash3(f,g,h,hash->shift);
12176  item = hash->bucket[posn];
12177  prev = NULL;
12178 
12179  while (item != NULL) {
12180  DdNodePtr *key = item->key;
12181  if ((f == key[0]) && (g == key[1]) && (h == key[2])) {
12182  DdNode *value = item->value;
12183  cuddSatDec(item->count);
12184  if (item->count == 0) {
12185  cuddDeref(value);
12186  if (prev == NULL) {
12187  hash->bucket[posn] = item->next;
12188  } else {
12189  prev->next = item->next;
12190  }
12191  item->next = hash->nextFree;
12192  hash->nextFree = item;
12193  hash->size--;
12194  }
12195  return(value);
12196  }
12197  prev = item;
12198  item = item->next;
12199  }
12200  return(NULL);
12201 
12202 } /* end of cuddHashTableLookup3 */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
#define ddLCHash3(f, g, h, shift)
Definition: cuddInt.c:11320
#define assert(ex)
Definition: util.h:141
ptrint count
Definition: cuddInt.h:282
struct DdHashItem * next
Definition: cuddInt.h:281
DdHashItem * nextFree
Definition: cuddInt.h:292
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdNode * key[1]
Definition: cuddInt.h:284
int shift
Definition: cuddInt.h:295

◆ cuddHashTableQuit()

void cuddHashTableQuit ( DdHashTable hash)

Function********************************************************************

Synopsis [Shuts down a hash table.]

Description [Shuts down a hash table, dereferencing all the values.]

SideEffects [None]

SeeAlso [cuddHashTableInit]

Definition at line 11598 of file cuddInt.c.

11600 {
11601  unsigned int i;
11602  DdManager *dd = hash->manager;
11603  DdHashItem *bucket;
11604  DdHashItem **memlist, **nextmem;
11605  unsigned int numBuckets = hash->numBuckets;
11606 
11607  for (i = 0; i < numBuckets; i++) {
11608  bucket = hash->bucket[i];
11609  while (bucket != NULL) {
11610  Cudd_RecursiveDeref(dd, bucket->value);
11611  bucket = bucket->next;
11612  }
11613  }
11614 
11615  memlist = hash->memoryList;
11616  while (memlist != NULL) {
11617  nextmem = (DdHashItem **) memlist[0];
11618  FREE(memlist);
11619  memlist = nextmem;
11620  }
11621 
11622  FREE(hash->bucket);
11623  FREE(hash);
11624 
11625  return;
11626 
11627 } /* end of cuddHashTableQuit */
DdHashItem ** bucket
Definition: cuddInt.h:291
DdNode * value
Definition: cuddInt.h:283
#define FREE(obj)
Definition: util.h:80
DdManager * manager
Definition: cuddInt.h:298
struct DdHashItem * next
Definition: cuddInt.h:281
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
unsigned int numBuckets
Definition: cuddInt.h:294
DdHashItem ** memoryList
Definition: cuddInt.h:293

◆ cuddHashTableResize()

static int cuddHashTableResize ( DdHashTable hash)
static

Function********************************************************************

Synopsis [Resizes a hash table.]

Description [Resizes a hash table. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddHashTableInsert]

Definition at line 12392 of file cuddInt.c.

12394 {
12395  int j;
12396  unsigned int posn;
12397  DdHashItem *item;
12398  DdHashItem *next;
12399  DdNode **key;
12400  int numBuckets;
12401  DdHashItem **buckets;
12402  DdHashItem **oldBuckets = hash->bucket;
12403  int shift;
12404  int oldNumBuckets = hash->numBuckets;
12405  extern DD_OOMFP MMoutOfMemory;
12406  DD_OOMFP saveHandler;
12407 
12408  /* Compute the new size of the table. */
12409  numBuckets = oldNumBuckets << 1;
12410  saveHandler = MMoutOfMemory;
12411  MMoutOfMemory = Cudd_OutOfMem;
12412  buckets = ALLOC(DdHashItem *, numBuckets);
12413  MMoutOfMemory = saveHandler;
12414  if (buckets == NULL) {
12415  hash->maxsize <<= 1;
12416  return(1);
12417  }
12418 
12419  hash->bucket = buckets;
12420  hash->numBuckets = numBuckets;
12421  shift = --(hash->shift);
12422  hash->maxsize <<= 1;
12423  memset(buckets, 0, numBuckets * sizeof(DdHashItem *));
12424  if (hash->keysize == 1) {
12425  for (j = 0; j < oldNumBuckets; j++) {
12426  item = oldBuckets[j];
12427  while (item != NULL) {
12428  next = item->next;
12429  key = item->key;
12430  posn = ddLCHash2(key[0], key[0], shift);
12431  item->next = buckets[posn];
12432  buckets[posn] = item;
12433  item = next;
12434  }
12435  }
12436  } else if (hash->keysize == 2) {
12437  for (j = 0; j < oldNumBuckets; j++) {
12438  item = oldBuckets[j];
12439  while (item != NULL) {
12440  next = item->next;
12441  key = item->key;
12442  posn = ddLCHash2(key[0], key[1], shift);
12443  item->next = buckets[posn];
12444  buckets[posn] = item;
12445  item = next;
12446  }
12447  }
12448  } else if (hash->keysize == 3) {
12449  for (j = 0; j < oldNumBuckets; j++) {
12450  item = oldBuckets[j];
12451  while (item != NULL) {
12452  next = item->next;
12453  key = item->key;
12454  posn = ddLCHash3(key[0], key[1], key[2], shift);
12455  item->next = buckets[posn];
12456  buckets[posn] = item;
12457  item = next;
12458  }
12459  }
12460  } else {
12461  for (j = 0; j < oldNumBuckets; j++) {
12462  item = oldBuckets[j];
12463  while (item != NULL) {
12464  next = item->next;
12465  posn = ddLCHash(item->key, hash->keysize, shift);
12466  item->next = buckets[posn];
12467  buckets[posn] = item;
12468  item = next;
12469  }
12470  }
12471  }
12472  FREE(oldBuckets);
12473  return(1);
12474 
12475 } /* end of cuddHashTableResize */
unsigned int keysize
Definition: cuddInt.h:289
DdHashItem ** bucket
Definition: cuddInt.h:291
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
#define ddLCHash3(f, g, h, shift)
Definition: cuddInt.c:11320
struct DdHashItem * next
Definition: cuddInt.h:281
void(* DD_OOMFP)(long)
Definition: cudd.h:300
char * memset()
#define ALLOC(type, num)
Definition: util.h:76
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddInt.c:12304
unsigned int numBuckets
Definition: cuddInt.h:294
unsigned int maxsize
Definition: cuddInt.h:297
void(* MMoutOfMemory)(long)
Definition: util.c:105
DdNode * key[1]
Definition: cuddInt.h:284
void Cudd_OutOfMem(long size)
Definition: cuddInt.c:22982
#define ddLCHash2(f, g, shift)
Definition: cuddInt.c:11304
int shift
Definition: cuddInt.h:295

◆ cuddHeapProfile()

int cuddHeapProfile ( DdManager dd)

Function********************************************************************

Synopsis [Prints information about the heap.]

Description [Prints to the manager's stdout the number of live nodes for each level of the DD heap that contains at least one live node. It also prints a summary containing:

  • total number of tables;
  • number of tables with live nodes;
  • table with the largest number of live nodes;
  • number of nodes in that table.

If more than one table contains the maximum number of live nodes, only the one of lowest index is reported. Returns 1 in case of success and 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 5758 of file cuddInt.c.

5760 {
5761  int ntables = dd->size;
5762  DdSubtable *subtables = dd->subtables;
5763  int i, /* loop index */
5764  nodes, /* live nodes in i-th layer */
5765  retval, /* return value of fprintf */
5766  largest = -1, /* index of the table with most live nodes */
5767  maxnodes = -1, /* maximum number of live nodes in a table */
5768  nonempty = 0; /* number of tables with live nodes */
5769 
5770  /* Print header. */
5771 #if SIZEOF_VOID_P == 8
5772  retval = fprintf(dd->out,"*** DD heap profile for 0x%lx ***\n",
5773  (ptruint) dd);
5774 #else
5775  retval = fprintf(dd->out,"*** DD heap profile for 0x%x ***\n",
5776  (ptruint) dd);
5777 #endif
5778  if (retval == EOF) return 0;
5779 
5780  /* Print number of live nodes for each nonempty table. */
5781  for (i=0; i<ntables; i++) {
5782  nodes = subtables[i].keys - subtables[i].dead;
5783  if (nodes) {
5784  nonempty++;
5785  retval = fprintf(dd->out,"%5d: %5d nodes\n", i, nodes);
5786  if (retval == EOF) return 0;
5787  if (nodes > maxnodes) {
5788  maxnodes = nodes;
5789  largest = i;
5790  }
5791  }
5792  }
5793 
5794  nodes = dd->constants.keys - dd->constants.dead;
5795  if (nodes) {
5796  nonempty++;
5797  retval = fprintf(dd->out,"const: %5d nodes\n", nodes);
5798  if (retval == EOF) return 0;
5799  if (nodes > maxnodes) {
5800  maxnodes = nodes;
5801  largest = CUDD_CONST_INDEX;
5802  }
5803  }
5804 
5805  /* Print summary. */
5806  retval = fprintf(dd->out,"Summary: %d tables, %d non-empty, largest: %d ",
5807  ntables+1, nonempty, largest);
5808  if (retval == EOF) return 0;
5809  retval = fprintf(dd->out,"(with %d nodes)\n", maxnodes);
5810  if (retval == EOF) return 0;
5811 
5812  return(1);
5813 
5814 } /* end of cuddHeapProfile */
unsigned int keys
Definition: cuddInt.h:314
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
static int largest(void)
Definition: cuddInt.c:7968
unsigned int dead
Definition: cuddInt.h:316
FILE * out
Definition: cuddInt.h:423
#define CUDD_CONST_INDEX
Definition: cudd.h:107
unsigned int ptruint
Definition: cuddInt.h:250
DdSubtable constants
Definition: cuddInt.h:351

◆ cuddInitCache()

int cuddInitCache ( DdManager unique,
unsigned int  cacheSize,
unsigned int  maxCacheSize 
)

CFile***********************************************************************

FileName [cuddCache.c]

PackageName [cudd]

Synopsis [Functions for cache insertion and lookup.]

Description [Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Initializes the computed table.]

Description [Initializes the computed table. It is called by Cudd_Init. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_Init]

Definition at line 4198 of file cuddInt.c.

4202 {
4203  int i;
4204  unsigned int logSize;
4205 #ifndef DD_CACHE_PROFILE
4206  DdNodePtr *mem;
4207  ptruint offset;
4208 #endif
4209 
4210  /* Round cacheSize to largest power of 2 not greater than the requested
4211  ** initial cache size. */
4212  logSize = cuddComputeFloorLog2(ddMax(cacheSize,unique->slots/2));
4213  cacheSize = 1 << logSize;
4214  unique->acache = ALLOC(DdCache,cacheSize+1);
4215  if (unique->acache == NULL) {
4216  unique->errorCode = CUDD_MEMORY_OUT;
4217  return(0);
4218  }
4219  /* If the size of the cache entry is a power of 2, we want to
4220  ** enforce alignment to that power of two. This happens when
4221  ** DD_CACHE_PROFILE is not defined. */
4222 #ifdef DD_CACHE_PROFILE
4223  unique->cache = unique->acache;
4224  unique->memused += (cacheSize) * sizeof(DdCache);
4225 #else
4226  mem = (DdNodePtr *) unique->acache;
4227  offset = (ptruint) mem & (sizeof(DdCache) - 1);
4228  mem += (sizeof(DdCache) - offset) / sizeof(DdNodePtr);
4229  unique->cache = (DdCache *) mem;
4230  assert(((ptruint) unique->cache & (sizeof(DdCache) - 1)) == 0);
4231  unique->memused += (cacheSize+1) * sizeof(DdCache);
4232 #endif
4233  unique->cacheSlots = cacheSize;
4234  unique->cacheShift = sizeof(int) * 8 - logSize;
4235  unique->maxCacheHard = maxCacheSize;
4236  /* If cacheSlack is non-negative, we can resize. */
4237  unique->cacheSlack = (int) ddMin(maxCacheSize,
4239  2 * (int) cacheSize;
4240  Cudd_SetMinHit(unique,DD_MIN_HIT);
4241  /* Initialize to avoid division by 0 and immediate resizing. */
4242  unique->cacheMisses = (double) (int) (cacheSize * unique->minHit + 1);
4243  unique->cacheHits = 0;
4244  unique->totCachehits = 0;
4245  /* The sum of cacheMisses and totCacheMisses is always correct,
4246  ** even though cacheMisses is larger than it should for the reasons
4247  ** explained above. */
4248  unique->totCacheMisses = -unique->cacheMisses;
4249  unique->cachecollisions = 0;
4250  unique->cacheinserts = 0;
4251  unique->cacheLastInserts = 0;
4252  unique->cachedeletions = 0;
4253 
4254  /* Initialize the cache */
4255  for (i = 0; (unsigned) i < cacheSize; i++) {
4256  unique->cache[i].h = 0; /* unused slots */
4257  unique->cache[i].data = NULL; /* invalid entry */
4258 #ifdef DD_CACHE_PROFILE
4259  unique->cache[i].count = 0;
4260 #endif
4261  }
4262 
4263  return(1);
4264 
4265 } /* end of cuddInitCache */
Definition: cudd.h:264
DdNode * data
Definition: cuddInt.h:304
#define assert(ex)
Definition: util.h:141
unsigned int maxCacheHard
Definition: cuddInt.h:343
unsigned int slots
Definition: cuddInt.h:352
ptruint h
Definition: cuddInt.h:303
double cachecollisions
Definition: cuddInt.h:437
DdNode * DdNodePtr
Definition: cuddInt.h:253
void Cudd_SetMinHit(DdManager *dd, unsigned int hr)
Definition: cuddInt.c:1763
#define DD_MIN_HIT
Definition: cuddInt.h:137
double cacheinserts
Definition: cuddInt.h:438
unsigned int cacheSlots
Definition: cuddInt.h:337
#define ALLOC(type, num)
Definition: util.h:76
DdCache * cache
Definition: cuddInt.h:336
double totCacheMisses
Definition: cuddInt.h:436
#define ddMax(x, y)
Definition: cuddInt.h:785
double cacheLastInserts
Definition: cuddInt.h:439
double cacheHits
Definition: cuddInt.h:340
#define ddMin(x, y)
Definition: cuddInt.h:771
#define DD_MAX_CACHE_TO_SLOTS_RATIO
Definition: cuddInt.h:145
int cacheSlack
Definition: cuddInt.h:342
unsigned long memused
Definition: cuddInt.h:429
unsigned int ptruint
Definition: cuddInt.h:250
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddInt.c:5102
double cacheMisses
Definition: cuddInt.h:339
double minHit
Definition: cuddInt.h:341
int cacheShift
Definition: cuddInt.h:338
double cachedeletions
Definition: cuddInt.h:440
DdCache * acache
Definition: cuddInt.h:335
struct DdCache DdCache
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
double totCachehits
Definition: cuddInt.h:435

◆ cuddInitInteract()

int cuddInitInteract ( DdManager table)

Function********************************************************************

Synopsis [Initializes the interaction matrix.]

Description [Initializes the interaction matrix. The interaction matrix is implemented as a bit vector storing the upper triangle of the symmetric interaction matrix. The bit vector is kept in an array of long integers. The computation is based on a series of depth-first searches, one for each root of the DAG. Two flags are needed: The local visited flag uses the LSB of the then pointer. The global visited flag uses the LSB of the next pointer. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 10963 of file cuddInt.c.

10965 {
10966  int i,j;
10967  unsigned long words;
10968  long *interact;
10969  char *support;
10970  DdNode *f;
10971  DdNode *sentinel = &(table->sentinel);
10972  DdNodePtr *nodelist;
10973  int slots;
10974  unsigned long n = (unsigned long) table->size;
10975 
10976  words = ((n * (n-1)) >> (1 + LOGBPL)) + 1;
10977  table->interact = interact = ALLOC(long,words);
10978  if (interact == NULL) {
10979  table->errorCode = CUDD_MEMORY_OUT;
10980  return(0);
10981  }
10982  for (i = 0; i < words; i++) {
10983  interact[i] = 0;
10984  }
10985 
10986  support = ALLOC(char,n);
10987  if (support == NULL) {
10988  table->errorCode = CUDD_MEMORY_OUT;
10989  FREE(interact);
10990  return(0);
10991  }
10992  for (i = 0; i < n; i++) {
10993  support[i] = 0;
10994  }
10995 
10996  for (i = 0; i < n; i++) {
10997  nodelist = table->subtables[i].nodelist;
10998  slots = table->subtables[i].slots;
10999  for (j = 0; j < slots; j++) {
11000  f = nodelist[j];
11001  while (f != sentinel) {
11002  /* A node is a root of the DAG if it cannot be
11003  ** reached by nodes above it. If a node was never
11004  ** reached during the previous depth-first searches,
11005  ** then it is a root, and we start a new depth-first
11006  ** search from it.
11007  */
11008  if (!Cudd_IsComplement(f->next)) {
11009  ddSuppInteract(f,support);
11010  ddClearLocal(f);
11011  ddUpdateInteract(table,support);
11012  }
11013  f = Cudd_Regular(f->next);
11014  }
11015  }
11016  }
11017  ddClearGlobal2(table);
11018 
11019  FREE(support);
11020  return(1);
11021 
11022 } /* end of cuddInitInteract */
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
int size
Definition: cuddInt.h:345
#define Cudd_Regular(node)
Definition: cudd.h:373
static void ddSuppInteract(DdNode *f, char *support)
Definition: cuddInt.c:11043
static void ddClearLocal(DdNode *f)
Definition: cuddInt.c:11074
DdSubtable * subtables
Definition: cuddInt.h:349
static void ddUpdateInteract(DdManager *table, char *support)
Definition: cuddInt.c:11103
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode sentinel
Definition: cuddInt.h:328
#define ALLOC(type, num)
Definition: util.h:76
DdNode * next
Definition: cudd.h:267
long * interact
Definition: cuddInt.h:377
DdNode ** nodelist
Definition: cuddInt.h:311
#define LOGBPL
Definition: cuddInt.c:12625
static void ddClearGlobal2(DdManager *table)
Definition: cuddInt.c:11139
unsigned int slots
Definition: cuddInt.h:313
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddInitLinear()

int cuddInitLinear ( DdManager table)

Function********************************************************************

Synopsis [Initializes the linear transform matrix.]

Description [Initializes the linear transform matrix. Returns 1 if successful; 0 otherwise.]

SideEffects [none]

SeeAlso []

Definition at line 13269 of file cuddInt.c.

13271 {
13272  int words;
13273  int wordsPerRow;
13274  int nvars;
13275  int word;
13276  int bit;
13277  int i;
13278  long *linear;
13279 
13280  nvars = table->size;
13281  wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
13282  words = wordsPerRow * nvars;
13283  table->linear = linear = ALLOC(long,words);
13284  if (linear == NULL) {
13285  table->errorCode = CUDD_MEMORY_OUT;
13286  return(0);
13287  }
13288  table->memused += words * sizeof(long);
13289  table->linearSize = nvars;
13290  for (i = 0; i < words; i++) linear[i] = 0;
13291  for (i = 0; i < nvars; i++) {
13292  word = wordsPerRow * i + (i >> LOGBPL);
13293  bit = i & (BPL-1);
13294  linear[word] = 1 << bit;
13295  }
13296  return(1);
13297 
13298 } /* end of cuddInitLinear */
int size
Definition: cuddInt.h:345
#define BPL
Definition: cuddInt.c:12624
#define ALLOC(type, num)
Definition: util.h:76
long * linear
Definition: cuddInt.h:378
int linearSize
Definition: cuddInt.h:376
#define LOGBPL
Definition: cuddInt.c:12625
unsigned long memused
Definition: cuddInt.h:429
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddInitTable()

DdManager* cuddInitTable ( unsigned int  numVars,
unsigned int  numVarsZ,
unsigned int  numSlots,
unsigned int  looseUpTo 
)

Function********************************************************************

Synopsis [Creates and initializes the unique table.]

Description [Creates and initializes the unique table. Returns a pointer to the table if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [Cudd_Init cuddFreeTable]

Definition at line 19738 of file cuddInt.c.

19743 {
19744 DdManager *unique = ALLOC(DdManager,1);
19745 int i, j;
19746 DdNodePtr *nodelist;
19747 DdNode *sentinel;
19748 unsigned int slots;
19749 int shift;
19750 
19751 if (unique == NULL) {
19752 return(NULL);
19753 }
19754 sentinel = &(unique->sentinel);
19755 sentinel->ref = 0;
19756 sentinel->index = 0;
19757 cuddT(sentinel) = NULL;
19758 cuddE(sentinel) = NULL;
19759 sentinel->next = NULL;
19760 unique->epsilon = DD_EPSILON;
19761 unique->size = numVars;
19762 unique->sizeZ = numVarsZ;
19763 unique->maxSize = ddMax(DD_DEFAULT_RESIZE, numVars);
19764 unique->maxSizeZ = ddMax(DD_DEFAULT_RESIZE, numVarsZ);
19765 
19766 /* Adjust the requested number of slots to a power of 2. */
19767 slots = 8;
19768 while (slots < numSlots) {
19769 slots <<= 1;
19770 }
19771 unique->initSlots = slots;
19772 shift = sizeof(int) * 8 - cuddComputeFloorLog2(slots);
19773 
19774 unique->slots = (numVars + numVarsZ + 1) * slots;
19775 unique->keys = 0;
19776 unique->maxLive = ~0; /* very large number */
19777 unique->keysZ = 0;
19778 unique->dead = 0;
19779 unique->deadZ = 0;
19780 unique->gcFrac = DD_GC_FRAC_HI;
19781 unique->minDead = (unsigned) (DD_GC_FRAC_HI * (double) unique->slots);
19782 unique->looseUpTo = looseUpTo;
19783 unique->gcEnabled = 1;
19784 unique->allocated = 0;
19785 unique->reclaimed = 0;
19786 unique->subtables = ALLOC(DdSubtable,unique->maxSize);
19787 if (unique->subtables == NULL) {
19788 FREE(unique);
19789 return(NULL);
19790 }
19791 unique->subtableZ = ALLOC(DdSubtable,unique->maxSizeZ);
19792 if (unique->subtableZ == NULL) {
19793 FREE(unique->subtables);
19794 FREE(unique);
19795 return(NULL);
19796 }
19797 unique->perm = ALLOC(int,unique->maxSize);
19798 if (unique->perm == NULL) {
19799 FREE(unique->subtables);
19800 FREE(unique->subtableZ);
19801 FREE(unique);
19802 return(NULL);
19803 }
19804 unique->invperm = ALLOC(int,unique->maxSize);
19805 if (unique->invperm == NULL) {
19806 FREE(unique->subtables);
19807 FREE(unique->subtableZ);
19808 FREE(unique->perm);
19809 FREE(unique);
19810 return(NULL);
19811 }
19812 unique->permZ = ALLOC(int,unique->maxSizeZ);
19813 if (unique->permZ == NULL) {
19814 FREE(unique->subtables);
19815 FREE(unique->subtableZ);
19816 FREE(unique->perm);
19817 FREE(unique->invperm);
19818 FREE(unique);
19819 return(NULL);
19820 }
19821 unique->invpermZ = ALLOC(int,unique->maxSizeZ);
19822 if (unique->invpermZ == NULL) {
19823 FREE(unique->subtables);
19824 FREE(unique->subtableZ);
19825 FREE(unique->perm);
19826 FREE(unique->invperm);
19827 FREE(unique->permZ);
19828 FREE(unique);
19829 return(NULL);
19830 }
19831 unique->map = NULL;
19832 unique->stack = ALLOC(DdNodePtr,ddMax(unique->maxSize,unique->maxSizeZ)+1);
19833 if (unique->stack == NULL) {
19834 FREE(unique->subtables);
19835 FREE(unique->subtableZ);
19836 FREE(unique->perm);
19837 FREE(unique->invperm);
19838 FREE(unique->permZ);
19839 FREE(unique->invpermZ);
19840 FREE(unique);
19841 return(NULL);
19842 }
19843 unique->stack[0] = NULL; /* to suppress harmless UMR */
19844 
19845 #ifndef DD_NO_DEATH_ROW
19846 unique->deathRowDepth = 1 << cuddComputeFloorLog2(unique->looseUpTo >> 2);
19847 unique->deathRow = ALLOC(DdNodePtr,unique->deathRowDepth);
19848 if (unique->deathRow == NULL) {
19849 FREE(unique->subtables);
19850 FREE(unique->subtableZ);
19851 FREE(unique->perm);
19852 FREE(unique->invperm);
19853 FREE(unique->permZ);
19854 FREE(unique->invpermZ);
19855 FREE(unique->stack);
19856 FREE(unique);
19857 return(NULL);
19858 }
19859 for (i = 0; i < unique->deathRowDepth; i++) {
19860 unique->deathRow[i] = NULL;
19861 }
19862 unique->nextDead = 0;
19863 unique->deadMask = unique->deathRowDepth - 1;
19864 #endif
19865 
19866 for (i = 0; (unsigned) i < numVars; i++) {
19867 unique->subtables[i].slots = slots;
19868 unique->subtables[i].shift = shift;
19869 unique->subtables[i].keys = 0;
19870 unique->subtables[i].dead = 0;
19871 unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
19872 unique->subtables[i].bindVar = 0;
19874 unique->subtables[i].pairIndex = 0;
19875 unique->subtables[i].varHandled = 0;
19877 
19878 nodelist = unique->subtables[i].nodelist = ALLOC(DdNodePtr,slots);
19879 if (nodelist == NULL) {
19880 for (j = 0; j < i; j++) {
19881 FREE(unique->subtables[j].nodelist);
19882 }
19883 FREE(unique->subtables);
19884 FREE(unique->subtableZ);
19885 FREE(unique->perm);
19886 FREE(unique->invperm);
19887 FREE(unique->permZ);
19888 FREE(unique->invpermZ);
19889 FREE(unique->stack);
19890 FREE(unique);
19891 return(NULL);
19892 }
19893 for (j = 0; (unsigned) j < slots; j++) {
19894 nodelist[j] = sentinel;
19895 }
19896 unique->perm[i] = i;
19897 unique->invperm[i] = i;
19898 }
19899 for (i = 0; (unsigned) i < numVarsZ; i++) {
19900 unique->subtableZ[i].slots = slots;
19901 unique->subtableZ[i].shift = shift;
19902 unique->subtableZ[i].keys = 0;
19903 unique->subtableZ[i].dead = 0;
19904 unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
19905 nodelist = unique->subtableZ[i].nodelist = ALLOC(DdNodePtr,slots);
19906 if (nodelist == NULL) {
19907 for (j = 0; (unsigned) j < numVars; j++) {
19908 FREE(unique->subtables[j].nodelist);
19909 }
19910 FREE(unique->subtables);
19911 for (j = 0; j < i; j++) {
19912 FREE(unique->subtableZ[j].nodelist);
19913 }
19914 FREE(unique->subtableZ);
19915 FREE(unique->perm);
19916 FREE(unique->invperm);
19917 FREE(unique->permZ);
19918 FREE(unique->invpermZ);
19919 FREE(unique->stack);
19920 FREE(unique);
19921 return(NULL);
19922 }
19923 for (j = 0; (unsigned) j < slots; j++) {
19924 nodelist[j] = NULL;
19925 }
19926 unique->permZ[i] = i;
19927 unique->invpermZ[i] = i;
19928 }
19929 unique->constants.slots = slots;
19930 unique->constants.shift = shift;
19931 unique->constants.keys = 0;
19932 unique->constants.dead = 0;
19933 unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
19934 nodelist = unique->constants.nodelist = ALLOC(DdNodePtr,slots);
19935 if (nodelist == NULL) {
19936 for (j = 0; (unsigned) j < numVars; j++) {
19937 FREE(unique->subtables[j].nodelist);
19938 }
19939 FREE(unique->subtables);
19940 for (j = 0; (unsigned) j < numVarsZ; j++) {
19941 FREE(unique->subtableZ[j].nodelist);
19942 }
19943 FREE(unique->subtableZ);
19944 FREE(unique->perm);
19945 FREE(unique->invperm);
19946 FREE(unique->permZ);
19947 FREE(unique->invpermZ);
19948 FREE(unique->stack);
19949 FREE(unique);
19950 return(NULL);
19951 }
19952 for (j = 0; (unsigned) j < slots; j++) {
19953 nodelist[j] = NULL;
19954 }
19955 
19956 unique->memoryList = NULL;
19957 unique->nextFree = NULL;
19958 
19959 unique->memused = sizeof(DdManager) + (unique->maxSize + unique->maxSizeZ)
19960 * (sizeof(DdSubtable) + 2 * sizeof(int)) + (numVars + 1) *
19961 slots * sizeof(DdNodePtr) +
19962 (ddMax(unique->maxSize,unique->maxSizeZ) + 1) * sizeof(DdNodePtr);
19963 #ifndef DD_NO_DEATH_ROW
19964 unique->memused += unique->deathRowDepth * sizeof(DdNodePtr);
19965 #endif
19966 
19967 /* Initialize fields concerned with automatic dynamic reordering. */
19968 unique->reordered = 0;
19969 unique->reorderings = 0;
19970 unique->maxReorderings = ~0;
19971 unique->siftMaxVar = DD_SIFT_MAX_VAR;
19972 unique->siftMaxSwap = DD_SIFT_MAX_SWAPS;
19974 unique->maxGrowthAlt = 2.0 * DD_MAX_REORDER_GROWTH;
19975 unique->reordCycle = 0; /* do not use alternate threshold */
19976 unique->autoDyn = 0; /* initially disabled */
19977 unique->autoDynZ = 0; /* initially disabled */
19978 unique->autoMethod = CUDD_REORDER_SIFT;
19979 unique->autoMethodZ = CUDD_REORDER_SIFT;
19980 unique->realign = 0; /* initially disabled */
19981 unique->realignZ = 0; /* initially disabled */
19982 unique->nextDyn = DD_FIRST_REORDER;
19983 unique->countDead = ~0;
19984 unique->tree = NULL;
19985 unique->treeZ = NULL;
19986 unique->groupcheck = CUDD_GROUP_CHECK7;
19987 unique->recomb = DD_DEFAULT_RECOMB;
19988 unique->symmviolation = 0;
19989 unique->arcviolation = 0;
19990 unique->populationSize = 0;
19991 unique->numberXovers = 0;
19992 unique->randomizeOrder = 0;
19993 unique->linear = NULL;
19994 unique->linearSize = 0;
19995 
19996 /* Initialize ZDD universe. */
19997 unique->univ = (DdNodePtr *)NULL;
19998 
19999 /* Initialize auxiliary fields. */
20000 unique->localCaches = NULL;
20001 unique->preGCHook = NULL;
20002 unique->postGCHook = NULL;
20003 unique->preReorderingHook = NULL;
20004 unique->postReorderingHook = NULL;
20005 unique->out = stdout;
20006 unique->err = stderr;
20007 unique->errorCode = CUDD_NO_ERROR;
20008 unique->startTime = util_cpu_time();
20009 unique->timeLimit = ~0UL;
20010 
20011 /* Initialize statistical counters. */
20012 unique->maxmemhard = ~ 0UL;
20013 unique->garbageCollections = 0;
20014 unique->GCTime = 0;
20015 unique->reordTime = 0;
20016 #ifdef DD_STATS
20017 unique->nodesDropped = 0;
20018 unique->nodesFreed = 0;
20019 #endif
20020 unique->peakLiveNodes = 0;
20021 #ifdef DD_UNIQUE_PROFILE
20022 unique->uniqueLookUps = 0;
20023 unique->uniqueLinks = 0;
20024 #endif
20025 #ifdef DD_COUNT
20026 unique->recursiveCalls = 0;
20027 unique->swapSteps = 0;
20028 #ifdef DD_STATS
20029 unique->nextSample = 250000;
20030 #endif
20031 #endif
20032 
20033 return(unique);
20034 
20035 } /* end of cuddInitTable */
DdHalfWord ref
Definition: cudd.h:266
Cudd_AggregationType groupcheck
Definition: cuddInt.h:410
unsigned int keys
Definition: cuddInt.h:314
unsigned long reordTime
Definition: cuddInt.h:434
Cudd_ReorderingType autoMethod
Definition: cuddInt.h:402
#define DD_SIFT_MAX_VAR
Definition: cuddInt.h:148
unsigned int peakLiveNodes
Definition: cuddInt.h:445
int maxSizeZ
Definition: cuddInt.h:348
double allocated
Definition: cuddInt.h:365
int * map
Definition: cuddInt.h:374
Definition: cudd.h:264
unsigned int deadZ
Definition: cuddInt.h:356
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
DdHook * preReorderingHook
Definition: cuddInt.h:421
unsigned deadMask
Definition: cuddInt.h:387
unsigned long startTime
Definition: cuddInt.h:426
int * invpermZ
Definition: cuddInt.h:372
int reordCycle
Definition: cuddInt.h:399
int size
Definition: cuddInt.h:345
double gcFrac
Definition: cuddInt.h:359
struct DdManager DdManager
Definition: cudd.h:274
unsigned int slots
Definition: cuddInt.h:352
double maxGrowthAlt
Definition: cuddInt.h:398
int realign
Definition: cuddInt.h:404
double maxGrowth
Definition: cuddInt.h:397
FILE * err
Definition: cuddInt.h:424
int garbageCollections
Definition: cuddInt.h:432
int populationSize
Definition: cuddInt.h:414
#define DD_FIRST_REORDER
Definition: cuddInt.h:152
Cudd_ReorderingType autoMethodZ
Definition: cuddInt.h:403
int bindVar
Definition: cuddInt.h:318
DdSubtable * subtables
Definition: cuddInt.h:349
int * permZ
Definition: cuddInt.h:370
DdNode * DdNodePtr
Definition: cuddInt.h:253
#define DD_EPSILON
Definition: cuddInt.h:110
MtrNode * tree
Definition: cuddInt.h:408
struct DdSubtable DdSubtable
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
#define DD_DEFAULT_RECOMB
Definition: cuddInt.h:150
DdNode ** deathRow
Definition: cuddInt.h:384
DdNode ** stack
Definition: cuddInt.h:364
unsigned int countDead
Definition: cuddInt.h:407
unsigned int initSlots
Definition: cuddInt.h:363
unsigned int randomizeOrder
Definition: cuddInt.h:416
Cudd_VariableType varType
Definition: cuddInt.h:320
int reordered
Definition: cuddInt.h:392
unsigned int nextDyn
Definition: cuddInt.h:406
#define DD_GC_FRAC_HI
Definition: cuddInt.h:135
unsigned int dead
Definition: cuddInt.h:355
unsigned int maxLive
Definition: cuddInt.h:357
int recomb
Definition: cuddInt.h:411
DdNode sentinel
Definition: cuddInt.h:328
DdHook * postReorderingHook
Definition: cuddInt.h:422
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
unsigned int dead
Definition: cuddInt.h:316
FILE * out
Definition: cuddInt.h:423
#define DD_SIFT_MAX_SWAPS
Definition: cuddInt.h:149
int realignZ
Definition: cuddInt.h:405
DdNode * next
Definition: cudd.h:267
Cudd_LazyGroupType varToBeGrouped
Definition: cuddInt.h:323
int maxSize
Definition: cuddInt.h:347
unsigned int maxKeys
Definition: cuddInt.h:315
long * linear
Definition: cuddInt.h:378
int gcEnabled
Definition: cuddInt.h:360
#define ddMax(x, y)
Definition: cuddInt.h:785
int symmviolation
Definition: cuddInt.h:412
int numberXovers
Definition: cuddInt.h:415
DdNode ** nodelist
Definition: cuddInt.h:311
int linearSize
Definition: cuddInt.h:376
DdLocalCache * localCaches
Definition: cuddInt.h:417
long util_cpu_time(void)
Definition: util.c:34
#define cuddT(node)
Definition: cuddInt.h:609
int nextDead
Definition: cuddInt.h:386
int varHandled
Definition: cuddInt.h:322
unsigned long GCTime
Definition: cuddInt.h:433
DdNode ** memoryList
Definition: cuddInt.h:380
unsigned int maxReorderings
Definition: cuddInt.h:394
unsigned long memused
Definition: cuddInt.h:429
int siftMaxVar
Definition: cuddInt.h:395
int deathRowDepth
Definition: cuddInt.h:385
DdNode * nextFree
Definition: cuddInt.h:381
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddInt.c:5102
#define DD_DEFAULT_RESIZE
Definition: cuddInt.h:103
int sizeZ
Definition: cuddInt.h:346
DdHalfWord index
Definition: cudd.h:265
unsigned int looseUpTo
Definition: cuddInt.h:361
unsigned int slots
Definition: cuddInt.h:313
unsigned int reorderings
Definition: cuddInt.h:393
unsigned long maxmemhard
Definition: cuddInt.h:431
DdHook * postGCHook
Definition: cuddInt.h:420
int pairIndex
Definition: cuddInt.h:321
#define DD_MAX_REORDER_GROWTH
Definition: cuddInt.h:151
CUDD_VALUE_TYPE epsilon
Definition: cuddInt.h:390
MtrNode * treeZ
Definition: cuddInt.h:409
int autoDynZ
Definition: cuddInt.h:401
#define cuddE(node)
Definition: cuddInt.h:625
int arcviolation
Definition: cuddInt.h:413
int * invperm
Definition: cuddInt.h:371
DdSubtable constants
Definition: cuddInt.h:351
int autoDyn
Definition: cuddInt.h:400
int shift
Definition: cuddInt.h:312
unsigned int keysZ
Definition: cuddInt.h:354
DdHook * preGCHook
Definition: cuddInt.h:419
int * perm
Definition: cuddInt.h:369
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
unsigned int minDead
Definition: cuddInt.h:358
double reclaimed
Definition: cuddInt.h:367
DdSubtable * subtableZ
Definition: cuddInt.h:350
DdNode ** univ
Definition: cuddInt.h:375

◆ cuddLinearAndSifting()

int cuddLinearAndSifting ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [BDD reduction based on combination of sifting and linear transformations.]

Description [BDD reduction based on combination of sifting and linear transformations. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique table.
  2. Sift the variable up and down, remembering each time the total size of the DD heap. At each position, linear transformation of the two adjacent variables is tried and is accepted if it reduces the size of the DD.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 12750 of file cuddInt.c.

12754 {
12755  int i;
12756  int *var;
12757  int size;
12758  int x;
12759  int result;
12760 #ifdef DD_STATS
12761  int previousSize;
12762 #endif
12763 
12764 #ifdef DD_STATS
12765  ddTotalNumberLinearTr = 0;
12766 #endif
12767 
12768  size = table->size;
12769 
12770  var = NULL;
12771  entry = NULL;
12772  if (table->linear == NULL) {
12773  result = cuddInitLinear(table);
12774  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
12775 #if 0
12776  (void) fprintf(table->out,"\n");
12777  result = Cudd_PrintLinear(table);
12778  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
12779 #endif
12780  } else if (table->size != table->linearSize) {
12781  result = cuddResizeLinear(table);
12782  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
12783 #if 0
12784  (void) fprintf(table->out,"\n");
12785  result = Cudd_PrintLinear(table);
12786  if (result == 0) goto cuddLinearAndSiftingOutOfMem;
12787 #endif
12788  }
12789 
12790  /* Find order in which to sift variables. */
12791  entry = ALLOC(int,size);
12792  if (entry == NULL) {
12793  table->errorCode = CUDD_MEMORY_OUT;
12794  goto cuddLinearAndSiftingOutOfMem;
12795  }
12796  var = ALLOC(int,size);
12797  if (var == NULL) {
12798  table->errorCode = CUDD_MEMORY_OUT;
12799  goto cuddLinearAndSiftingOutOfMem;
12800  }
12801 
12802  for (i = 0; i < size; i++) {
12803  x = table->perm[i];
12804  entry[i] = table->subtables[x].keys;
12805  var[i] = i;
12806  }
12807 
12808  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddLinearUniqueCompare);
12809 
12810  /* Now sift. */
12811  for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
12812  x = table->perm[var[i]];
12813  if (x < lower || x > upper) continue;
12814 #ifdef DD_STATS
12815  previousSize = table->keys - table->isolated;
12816 #endif
12817  result = ddLinearAndSiftingAux(table,x,lower,upper);
12818  if (!result) goto cuddLinearAndSiftingOutOfMem;
12819 #ifdef DD_STATS
12820  if (table->keys < (unsigned) previousSize + table->isolated) {
12821  (void) fprintf(table->out,"-");
12822  } else if (table->keys > (unsigned) previousSize + table->isolated) {
12823  (void) fprintf(table->out,"+"); /* should never happen */
12824  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]);
12825  } else {
12826  (void) fprintf(table->out,"=");
12827  }
12828  fflush(table->out);
12829 #endif
12830 #ifdef DD_DEBUG
12831  (void) Cudd_DebugCheck(table);
12832 #endif
12833  }
12834 
12835  FREE(var);
12836  FREE(entry);
12837 
12838 #ifdef DD_STATS
12839  (void) fprintf(table->out,"\n#:L_LINSIFT %8d: linear trans.",
12840  ddTotalNumberLinearTr);
12841 #endif
12842 
12843  return(1);
12844 
12845  cuddLinearAndSiftingOutOfMem:
12846 
12847  if (entry != NULL) FREE(entry);
12848  if (var != NULL) FREE(var);
12849 
12850  return(0);
12851 
12852 } /* end of cuddLinearAndSifting */
unsigned int keys
Definition: cuddInt.h:314
static int ddLinearAndSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddInt.c:13410
#define FREE(obj)
Definition: util.h:80
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:302
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
int Cudd_PrintLinear(DdManager *table)
Definition: cuddInt.c:12695
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static int ddLinearUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddInt.c:13382
long * linear
Definition: cuddInt.h:378
int linearSize
Definition: cuddInt.h:376
#define ddMin(x, y)
Definition: cuddInt.h:771
int cuddResizeLinear(DdManager *table)
Definition: cuddInt.c:13314
int siftMaxVar
Definition: cuddInt.h:395
static int result
Definition: cuddInt.c:7466
int Cudd_DebugCheck(DdManager *table)
Definition: cuddInt.c:5255
static int * entry
Definition: cuddInt.c:8422
int isolated
Definition: cuddInt.h:368
int * perm
Definition: cuddInt.h:369
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
int cuddInitLinear(DdManager *table)
Definition: cuddInt.c:13269

◆ cuddLinearInPlace()

int cuddLinearInPlace ( DdManager table,
int  x,
int  y 
)

Function********************************************************************

Synopsis [Linearly combines two adjacent variables.]

Description [Linearly combines two adjacent variables. Specifically, replaces the top variable with the exclusive nor of the two variables. It assumes that no dead nodes are present on entry to this procedure. The procedure then guarantees that no dead nodes will be present when it terminates. cuddLinearInPlace assumes that x < y. Returns the number of keys in the table if successful; 0 otherwise.]

SideEffects [The two subtables corrresponding to variables x and y are modified. The global counters of the unique table are also affected.]

SeeAlso [cuddSwapInPlace]

Definition at line 12874 of file cuddInt.c.

12878 {
12879  DdNodePtr *xlist, *ylist;
12880  int xindex, yindex;
12881  int xslots, yslots;
12882  int xshift, yshift;
12883  int oldxkeys, oldykeys;
12884  int newxkeys, newykeys;
12885  int comple, newcomplement;
12886  int i;
12887  int posn;
12888  int isolated;
12889  DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0;
12890  DdNode *g,*next,*last;
12891  DdNodePtr *previousP;
12892  DdNode *tmp;
12893  DdNode *sentinel = &(table->sentinel);
12894 #ifdef DD_DEBUG
12895  int count, idcheck;
12896 #endif
12897 
12898 #ifdef DD_DEBUG
12899  assert(x < y);
12900  assert(cuddNextHigh(table,x) == y);
12901  assert(table->subtables[x].keys != 0);
12902  assert(table->subtables[y].keys != 0);
12903  assert(table->subtables[x].dead == 0);
12904  assert(table->subtables[y].dead == 0);
12905 #endif
12906 
12907  xindex = table->invperm[x];
12908  yindex = table->invperm[y];
12909 
12910  if (cuddTestInteract(table,xindex,yindex)) {
12911 #ifdef DD_STATS
12912  ddTotalNumberLinearTr++;
12913 #endif
12914  /* Get parameters of x subtable. */
12915  xlist = table->subtables[x].nodelist;
12916  oldxkeys = table->subtables[x].keys;
12917  xslots = table->subtables[x].slots;
12918  xshift = table->subtables[x].shift;
12919 
12920  /* Get parameters of y subtable. */
12921  ylist = table->subtables[y].nodelist;
12922  oldykeys = table->subtables[y].keys;
12923  yslots = table->subtables[y].slots;
12924  yshift = table->subtables[y].shift;
12925 
12926  newxkeys = 0;
12927  newykeys = oldykeys;
12928 
12929  /* Check whether the two projection functions involved in this
12930  ** swap are isolated. At the end, we'll be able to tell how many
12931  ** isolated projection functions are there by checking only these
12932  ** two functions again. This is done to eliminate the isolated
12933  ** projection functions from the node count.
12934  */
12935  isolated = - ((table->vars[xindex]->ref == 1) +
12936  (table->vars[yindex]->ref == 1));
12937 
12938  /* The nodes in the x layer are put in a chain.
12939  ** The chain is handled as a FIFO; g points to the beginning and
12940  ** last points to the end.
12941  */
12942  g = NULL;
12943 #ifdef DD_DEBUG
12944  last = NULL;
12945 #endif
12946  for (i = 0; i < xslots; i++) {
12947  f = xlist[i];
12948  if (f == sentinel) continue;
12949  xlist[i] = sentinel;
12950  if (g == NULL) {
12951  g = f;
12952  } else {
12953  last->next = f;
12954  }
12955  while ((next = f->next) != sentinel) {
12956  f = next;
12957  } /* while there are elements in the collision chain */
12958  last = f;
12959  } /* for each slot of the x subtable */
12960 #ifdef DD_DEBUG
12961  /* last is always assigned in the for loop because there is at
12962  ** least one key */
12963  assert(last != NULL);
12964 #endif
12965  last->next = NULL;
12966 
12967 #ifdef DD_COUNT
12968  table->swapSteps += oldxkeys;
12969 #endif
12970  /* Take care of the x nodes that must be re-expressed.
12971  ** They form a linked list pointed by g.
12972  */
12973  f = g;
12974  while (f != NULL) {
12975  next = f->next;
12976  /* Find f1, f0, f11, f10, f01, f00. */
12977  f1 = cuddT(f);
12978 #ifdef DD_DEBUG
12979  assert(!(Cudd_IsComplement(f1)));
12980 #endif
12981  if ((int) f1->index == yindex) {
12982  f11 = cuddT(f1); f10 = cuddE(f1);
12983  } else {
12984  f11 = f10 = f1;
12985  }
12986 #ifdef DD_DEBUG
12987  assert(!(Cudd_IsComplement(f11)));
12988 #endif
12989  f0 = cuddE(f);
12990  comple = Cudd_IsComplement(f0);
12991  f0 = Cudd_Regular(f0);
12992  if ((int) f0->index == yindex) {
12993  f01 = cuddT(f0); f00 = cuddE(f0);
12994  } else {
12995  f01 = f00 = f0;
12996  }
12997  if (comple) {
12998  f01 = Cudd_Not(f01);
12999  f00 = Cudd_Not(f00);
13000  }
13001  /* Decrease ref count of f1. */
13002  cuddSatDec(f1->ref);
13003  /* Create the new T child. */
13004  if (f11 == f00) {
13005  newf1 = f11;
13006  cuddSatInc(newf1->ref);
13007  } else {
13008  /* Check ylist for triple (yindex,f11,f00). */
13009  posn = ddHash(f11, f00, yshift);
13010  /* For each element newf1 in collision list ylist[posn]. */
13011  previousP = &(ylist[posn]);
13012  newf1 = *previousP;
13013  while (f11 < cuddT(newf1)) {
13014  previousP = &(newf1->next);
13015  newf1 = *previousP;
13016  }
13017  while (f11 == cuddT(newf1) && f00 < cuddE(newf1)) {
13018  previousP = &(newf1->next);
13019  newf1 = *previousP;
13020  }
13021  if (cuddT(newf1) == f11 && cuddE(newf1) == f00) {
13022  cuddSatInc(newf1->ref);
13023  } else { /* no match */
13024  newf1 = cuddDynamicAllocNode(table);
13025  if (newf1 == NULL)
13026  goto cuddLinearOutOfMem;
13027  newf1->index = yindex; newf1->ref = 1;
13028  cuddT(newf1) = f11;
13029  cuddE(newf1) = f00;
13030  /* Insert newf1 in the collision list ylist[posn];
13031  ** increase the ref counts of f11 and f00.
13032  */
13033  newykeys++;
13034  newf1->next = *previousP;
13035  *previousP = newf1;
13036  cuddSatInc(f11->ref);
13037  tmp = Cudd_Regular(f00);
13038  cuddSatInc(tmp->ref);
13039  }
13040  }
13041  cuddT(f) = newf1;
13042 #ifdef DD_DEBUG
13043  assert(!(Cudd_IsComplement(newf1)));
13044 #endif
13045 
13046  /* Do the same for f0, keeping complement dots into account. */
13047  /* decrease ref count of f0 */
13048  tmp = Cudd_Regular(f0);
13049  cuddSatDec(tmp->ref);
13050  /* create the new E child */
13051  if (f01 == f10) {
13052  newf0 = f01;
13053  tmp = Cudd_Regular(newf0);
13054  cuddSatInc(tmp->ref);
13055  } else {
13056  /* make sure f01 is regular */
13057  newcomplement = Cudd_IsComplement(f01);
13058  if (newcomplement) {
13059  f01 = Cudd_Not(f01);
13060  f10 = Cudd_Not(f10);
13061  }
13062  /* Check ylist for triple (yindex,f01,f10). */
13063  posn = ddHash(f01, f10, yshift);
13064  /* For each element newf0 in collision list ylist[posn]. */
13065  previousP = &(ylist[posn]);
13066  newf0 = *previousP;
13067  while (f01 < cuddT(newf0)) {
13068  previousP = &(newf0->next);
13069  newf0 = *previousP;
13070  }
13071  while (f01 == cuddT(newf0) && f10 < cuddE(newf0)) {
13072  previousP = &(newf0->next);
13073  newf0 = *previousP;
13074  }
13075  if (cuddT(newf0) == f01 && cuddE(newf0) == f10) {
13076  cuddSatInc(newf0->ref);
13077  } else { /* no match */
13078  newf0 = cuddDynamicAllocNode(table);
13079  if (newf0 == NULL)
13080  goto cuddLinearOutOfMem;
13081  newf0->index = yindex; newf0->ref = 1;
13082  cuddT(newf0) = f01;
13083  cuddE(newf0) = f10;
13084  /* Insert newf0 in the collision list ylist[posn];
13085  ** increase the ref counts of f01 and f10.
13086  */
13087  newykeys++;
13088  newf0->next = *previousP;
13089  *previousP = newf0;
13090  cuddSatInc(f01->ref);
13091  tmp = Cudd_Regular(f10);
13092  cuddSatInc(tmp->ref);
13093  }
13094  if (newcomplement) {
13095  newf0 = Cudd_Not(newf0);
13096  }
13097  }
13098  cuddE(f) = newf0;
13099 
13100  /* Re-insert the modified f in xlist.
13101  ** The modified f does not already exists in xlist.
13102  ** (Because of the uniqueness of the cofactors.)
13103  */
13104  posn = ddHash(newf1, newf0, xshift);
13105  newxkeys++;
13106  previousP = &(xlist[posn]);
13107  tmp = *previousP;
13108  while (newf1 < cuddT(tmp)) {
13109  previousP = &(tmp->next);
13110  tmp = *previousP;
13111  }
13112  while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) {
13113  previousP = &(tmp->next);
13114  tmp = *previousP;
13115  }
13116  f->next = *previousP;
13117  *previousP = f;
13118  f = next;
13119  } /* while f != NULL */
13120 
13121  /* GC the y layer. */
13122 
13123  /* For each node f in ylist. */
13124  for (i = 0; i < yslots; i++) {
13125  previousP = &(ylist[i]);
13126  f = *previousP;
13127  while (f != sentinel) {
13128  next = f->next;
13129  if (f->ref == 0) {
13130  tmp = cuddT(f);
13131  cuddSatDec(tmp->ref);
13132  tmp = Cudd_Regular(cuddE(f));
13133  cuddSatDec(tmp->ref);
13134  cuddDeallocNode(table,f);
13135  newykeys--;
13136  } else {
13137  *previousP = f;
13138  previousP = &(f->next);
13139  }
13140  f = next;
13141  } /* while f */
13142  *previousP = sentinel;
13143  } /* for every collision list */
13144 
13145 #ifdef DD_DEBUG
13146  #if 0
13147  (void) fprintf(table->out,"Linearly combining %d and %d\n",x,y);
13148 #endif
13149  count = 0;
13150  idcheck = 0;
13151  for (i = 0; i < yslots; i++) {
13152  f = ylist[i];
13153  while (f != sentinel) {
13154  count++;
13155  if (f->index != (DdHalfWord) yindex)
13156  idcheck++;
13157  f = f->next;
13158  }
13159  }
13160  if (count != newykeys) {
13161  fprintf(table->err,"Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",oldykeys,newykeys,count);
13162  }
13163  if (idcheck != 0)
13164  fprintf(table->err,"Error in id's of ylist\twrong id's = %d\n",idcheck);
13165  count = 0;
13166  idcheck = 0;
13167  for (i = 0; i < xslots; i++) {
13168  f = xlist[i];
13169  while (f != sentinel) {
13170  count++;
13171  if (f->index != (DdHalfWord) xindex)
13172  idcheck++;
13173  f = f->next;
13174  }
13175  }
13176  if (count != newxkeys || newxkeys != oldxkeys) {
13177  fprintf(table->err,"Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",oldxkeys,newxkeys,count);
13178  }
13179  if (idcheck != 0)
13180  fprintf(table->err,"Error in id's of xlist\twrong id's = %d\n",idcheck);
13181 #endif
13182 
13183  isolated += (table->vars[xindex]->ref == 1) +
13184  (table->vars[yindex]->ref == 1);
13185  table->isolated += isolated;
13186 
13187  /* Set the appropriate fields in table. */
13188  table->subtables[y].keys = newykeys;
13189 
13190  /* Here we should update the linear combination table
13191  ** to record that x <- x EXNOR y. This is done by complementing
13192  ** the (x,y) entry of the table.
13193  */
13194 
13195  table->keys += newykeys - oldykeys;
13196 
13197  cuddXorLinear(table,xindex,yindex);
13198  }
13199 
13200 #ifdef DD_DEBUG
13201  if (zero) {
13202  (void) Cudd_DebugCheck(table);
13203  }
13204 #endif
13205 
13206  return(table->keys - table->isolated);
13207 
13208  cuddLinearOutOfMem:
13209  (void) fprintf(table->err,"Error: cuddLinearInPlace out of memory\n");
13210 
13211  return (0);
13212 
13213 } /* end of cuddLinearInPlace */
DdHalfWord ref
Definition: cudd.h:266
static void cuddXorLinear(DdManager *table, int x, int y)
Definition: cuddInt.c:13863
unsigned int keys
Definition: cuddInt.h:314
unsigned short DdHalfWord
Definition: cudd.h:253
#define ddHash(f, g, s)
Definition: cuddInt.h:696
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:373
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
FILE * err
Definition: cuddInt.h:424
DdSubtable * subtables
Definition: cuddInt.h:349
#define Cudd_IsComplement(node)
Definition: cudd.h:401
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
DdNode sentinel
Definition: cuddInt.h:328
unsigned int keys
Definition: cuddInt.h:353
unsigned int dead
Definition: cuddInt.h:316
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:267
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:520
DdHalfWord index
Definition: cudd.h:265
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
int Cudd_DebugCheck(DdManager *table)
Definition: cuddInt.c:5255
#define cuddSatDec(x)
Definition: cuddInt.h:849
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917
int * invperm
Definition: cuddInt.h:371
static DdNode * zero
Definition: cuddInt.c:16562
int isolated
Definition: cuddInt.h:368
int shift
Definition: cuddInt.h:312
#define cuddSatInc(x)
Definition: cuddInt.h:831

◆ cuddLocalCacheAddToList()

static void cuddLocalCacheAddToList ( DdLocalCache cache)
static

Function********************************************************************

Synopsis [Inserts a local cache in the manager list.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 12333 of file cuddInt.c.

12335 {
12336  DdManager *manager = cache->manager;
12337 
12338  cache->next = manager->localCaches;
12339  manager->localCaches = cache;
12340  return;
12341 
12342 } /* end of cuddLocalCacheAddToList */
struct DdLocalCache * next
Definition: cuddInt.h:276
DdLocalCache * localCaches
Definition: cuddInt.h:417
DdManager * manager
Definition: cuddInt.h:275

◆ cuddLocalCacheClearAll()

void cuddLocalCacheClearAll ( DdManager manager)

Function********************************************************************

Synopsis [Clears the local caches of a manager.]

Description [Clears the local caches of a manager. Used before reordering.]

SideEffects [None]

SeeAlso []

Definition at line 11414 of file cuddInt.c.

11416 {
11417  DdLocalCache *cache = manager->localCaches;
11418 
11419  while (cache != NULL) {
11420  memset(cache->item, 0, cache->slots * cache->itemsize);
11421  cache = cache->next;
11422  }
11423  return;
11424 
11425 } /* end of cuddLocalCacheClearAll */
DdLocalCacheItem * item
Definition: cuddInt.h:266
struct DdLocalCache * next
Definition: cuddInt.h:276
char * memset()
unsigned int itemsize
Definition: cuddInt.h:267
unsigned int slots
Definition: cuddInt.h:269
DdLocalCache * localCaches
Definition: cuddInt.h:417

◆ cuddLocalCacheClearDead()

void cuddLocalCacheClearDead ( DdManager manager)

AutomaticEnd Function********************************************************************

Synopsis [Clears the dead entries of the local caches of a manager.]

Description [Clears the dead entries of the local caches of a manager. Used during garbage collection.]

SideEffects [None]

SeeAlso []

Definition at line 11362 of file cuddInt.c.

11364 {
11365  DdLocalCache *cache = manager->localCaches;
11366  unsigned int keysize;
11367  unsigned int itemsize;
11368  unsigned int slots;
11369  DdLocalCacheItem *item;
11370  DdNodePtr *key;
11371  unsigned int i, j;
11372 
11373  while (cache != NULL) {
11374  keysize = cache->keysize;
11375  itemsize = cache->itemsize;
11376  slots = cache->slots;
11377  item = cache->item;
11378  for (i = 0; i < slots; i++) {
11379  if (item->value != NULL) {
11380  if (Cudd_Regular(item->value)->ref == 0) {
11381  item->value = NULL;
11382  } else {
11383  key = item->key;
11384  for (j = 0; j < keysize; j++) {
11385  if (Cudd_Regular(key[j])->ref == 0) {
11386  item->value = NULL;
11387  break;
11388  }
11389  }
11390  }
11391  }
11392  item = (DdLocalCacheItem *) ((char *) item + itemsize);
11393  }
11394  cache = cache->next;
11395  }
11396  return;
11397 
11398 } /* end of cuddLocalCacheClearDead */
Definition: cudd.h:264
#define Cudd_Regular(node)
Definition: cudd.h:373
DdNode * value
Definition: cuddInt.h:257
unsigned int keysize
Definition: cuddInt.h:268
DdLocalCacheItem * item
Definition: cuddInt.h:266
struct DdLocalCache * next
Definition: cuddInt.h:276
unsigned int itemsize
Definition: cuddInt.h:267
unsigned int slots
Definition: cuddInt.h:269
DdLocalCache * localCaches
Definition: cuddInt.h:417
DdNode * key[1]
Definition: cuddInt.h:261

◆ cuddLocalCacheRemoveFromList()

static void cuddLocalCacheRemoveFromList ( DdLocalCache cache)
static

Function********************************************************************

Synopsis [Removes a local cache from the manager list.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 12357 of file cuddInt.c.

12359 {
12360  DdManager *manager = cache->manager;
12361  DdLocalCache **prevCache, *nextCache;
12362 
12363  prevCache = &(manager->localCaches);
12364  nextCache = manager->localCaches;
12365 
12366  while (nextCache != NULL) {
12367  if (nextCache == cache) {
12368  *prevCache = nextCache->next;
12369  return;
12370  }
12371  prevCache = &(nextCache->next);
12372  nextCache = nextCache->next;
12373  }
12374  return; /* should never get here */
12375 
12376 } /* end of cuddLocalCacheRemoveFromList */
struct DdLocalCache * next
Definition: cuddInt.h:276
DdLocalCache * localCaches
Definition: cuddInt.h:417
DdManager * manager
Definition: cuddInt.h:275

◆ cuddLocalCacheResize()

static void cuddLocalCacheResize ( DdLocalCache cache)
static

AutomaticStart

Function********************************************************************

Synopsis [Resizes a local cache.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 12222 of file cuddInt.c.

12224 {
12225  DdLocalCacheItem *item, *olditem, *entry, *old;
12226  int i, shift;
12227  unsigned int posn;
12228  unsigned int slots, oldslots;
12229  extern DD_OOMFP MMoutOfMemory;
12230  DD_OOMFP saveHandler;
12231 
12232  olditem = cache->item;
12233  oldslots = cache->slots;
12234  slots = cache->slots = oldslots << 1;
12235 
12236 #ifdef DD_VERBOSE
12237  (void) fprintf(cache->manager->err,
12238  "Resizing local cache from %d to %d entries\n",
12239  oldslots, slots);
12240  (void) fprintf(cache->manager->err,
12241  "\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n",
12242  cache->hits, cache->lookUps, cache->hits / cache->lookUps);
12243 #endif
12244 
12245  saveHandler = MMoutOfMemory;
12246  MMoutOfMemory = Cudd_OutOfMem;
12247  cache->item = item =
12248  (DdLocalCacheItem *) ALLOC(char, slots * cache->itemsize);
12249  MMoutOfMemory = saveHandler;
12250  /* If we fail to allocate the new table we just give up. */
12251  if (item == NULL) {
12252 #ifdef DD_VERBOSE
12253  (void) fprintf(cache->manager->err,"Resizing failed. Giving up.\n");
12254 #endif
12255  cache->slots = oldslots;
12256  cache->item = olditem;
12257  /* Do not try to resize again. */
12258  cache->maxslots = oldslots - 1;
12259  return;
12260  }
12261  shift = --(cache->shift);
12262  cache->manager->memused += (slots - oldslots) * cache->itemsize;
12263 
12264  /* Clear new cache. */
12265  memset(item, 0, slots * cache->itemsize);
12266 
12267  /* Copy from old cache to new one. */
12268  for (i = 0; (unsigned) i < oldslots; i++) {
12269  old = (DdLocalCacheItem *) ((char *) olditem + i * cache->itemsize);
12270  if (old->value != NULL) {
12271  posn = ddLCHash(old->key,cache->keysize,shift);
12272  entry = (DdLocalCacheItem *) ((char *) item +
12273  posn * cache->itemsize);
12274  memcpy(entry->key,old->key,cache->keysize*sizeof(DdNode *));
12275  entry->value = old->value;
12276  }
12277  }
12278 
12279  FREE(olditem);
12280 
12281  /* Reinitialize measurements so as to avoid division by 0 and
12282  ** immediate resizing.
12283  */
12284  cache->lookUps = (double) (int) (slots * cache->minHit + 1);
12285  cache->hits = 0;
12286 
12287 } /* end of cuddLocalCacheResize */
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
char * memcpy()
FILE * err
Definition: cuddInt.h:424
DdNode * value
Definition: cuddInt.h:257
double minHit
Definition: cuddInt.h:272
unsigned int keysize
Definition: cuddInt.h:268
DdLocalCacheItem * item
Definition: cuddInt.h:266
void(* DD_OOMFP)(long)
Definition: cudd.h:300
unsigned int maxslots
Definition: cuddInt.h:274
char * memset()
unsigned int itemsize
Definition: cuddInt.h:267
#define ALLOC(type, num)
Definition: util.h:76
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddInt.c:12304
double hits
Definition: cuddInt.h:273
double lookUps
Definition: cuddInt.h:271
unsigned int slots
Definition: cuddInt.h:269
void(* MMoutOfMemory)(long)
Definition: util.c:105
unsigned long memused
Definition: cuddInt.h:429
DdNode * key[1]
Definition: cuddInt.h:261
void Cudd_OutOfMem(long size)
Definition: cuddInt.c:22982
static int * entry
Definition: cuddInt.c:8422
DdManager * manager
Definition: cuddInt.h:275

◆ cuddMakeBddFromZddCover()

DdNode* cuddMakeBddFromZddCover ( DdManager dd,
DdNode node 
)

Function********************************************************************

Synopsis [Converts a ZDD cover to a BDD.]

Description [Converts a ZDD cover to a BDD. If successful, it returns a BDD node, otherwise it returns NULL. It is a recursive algorithm that works as follows. First it computes 3 cofactors of a ZDD cover: f1, f0 and fd. Second, it compute BDDs (b1, b0 and bd) of f1, f0 and fd. Third, it computes T=b1+bd and E=b0+bd. Fourth, it computes ITE(v,T,E) where v is the variable which has the index of the top node of the ZDD cover. In this case, since the index of v can be larger than either the one of T or the one of E, cuddUniqueInterIVO is called, where IVO stands for independent from variable ordering.]

SideEffects []

SeeAlso [Cudd_MakeBddFromZddCover]

Definition at line 28360 of file cuddInt.c.

28363 {
28364  DdNode *neW;
28365  int v;
28366  DdNode *f1, *f0, *fd;
28367  DdNode *b1, *b0, *bd;
28368  DdNode *T, *E;
28369 
28370  statLine(dd);
28371  if (node == dd->one)
28372  return(dd->one);
28373  if (node == dd->zero)
28374  return(Cudd_Not(dd->one));
28375 
28376  /* Check cache */
28377  neW = cuddCacheLookup1(dd, cuddMakeBddFromZddCover, node);
28378  if (neW)
28379  return(neW);
28380 
28381  v = Cudd_Regular(node)->index; /* either yi or zi */
28382  if (cuddZddGetCofactors3(dd, node, v, &f1, &f0, &fd)) return(NULL);
28383  Cudd_Ref(f1);
28384  Cudd_Ref(f0);
28385  Cudd_Ref(fd);
28386 
28387  b1 = cuddMakeBddFromZddCover(dd, f1);
28388  if (!b1) {
28389  Cudd_RecursiveDerefZdd(dd, f1);
28390  Cudd_RecursiveDerefZdd(dd, f0);
28391  Cudd_RecursiveDerefZdd(dd, fd);
28392  return(NULL);
28393  }
28394  Cudd_Ref(b1);
28395  b0 = cuddMakeBddFromZddCover(dd, f0);
28396  if (!b0) {
28397  Cudd_RecursiveDerefZdd(dd, f1);
28398  Cudd_RecursiveDerefZdd(dd, f0);
28399  Cudd_RecursiveDerefZdd(dd, fd);
28400  Cudd_RecursiveDeref(dd, b1);
28401  return(NULL);
28402  }
28403  Cudd_Ref(b0);
28404  Cudd_RecursiveDerefZdd(dd, f1);
28405  Cudd_RecursiveDerefZdd(dd, f0);
28406  if (fd != dd->zero) {
28407  bd = cuddMakeBddFromZddCover(dd, fd);
28408  if (!bd) {
28409  Cudd_RecursiveDerefZdd(dd, fd);
28410  Cudd_RecursiveDeref(dd, b1);
28411  Cudd_RecursiveDeref(dd, b0);
28412  return(NULL);
28413  }
28414  Cudd_Ref(bd);
28415  Cudd_RecursiveDerefZdd(dd, fd);
28416 
28417  T = cuddBddAndRecur(dd, Cudd_Not(b1), Cudd_Not(bd));
28418  if (!T) {
28419  Cudd_RecursiveDeref(dd, b1);
28420  Cudd_RecursiveDeref(dd, b0);
28421  Cudd_RecursiveDeref(dd, bd);
28422  return(NULL);
28423  }
28424  T = Cudd_NotCond(T, T != NULL);
28425  Cudd_Ref(T);
28426  Cudd_RecursiveDeref(dd, b1);
28427  E = cuddBddAndRecur(dd, Cudd_Not(b0), Cudd_Not(bd));
28428  if (!E) {
28429  Cudd_RecursiveDeref(dd, b0);
28430  Cudd_RecursiveDeref(dd, bd);
28431  Cudd_RecursiveDeref(dd, T);
28432  return(NULL);
28433  }
28434  E = Cudd_NotCond(E, E != NULL);
28435  Cudd_Ref(E);
28436  Cudd_RecursiveDeref(dd, b0);
28437  Cudd_RecursiveDeref(dd, bd);
28438  }
28439  else {
28440  Cudd_RecursiveDerefZdd(dd, fd);
28441  T = b1;
28442  E = b0;
28443  }
28444 
28445  if (Cudd_IsComplement(T)) {
28446  neW = cuddUniqueInterIVO(dd, v / 2, Cudd_Not(T), Cudd_Not(E));
28447  if (!neW) {
28448  Cudd_RecursiveDeref(dd, T);
28449  Cudd_RecursiveDeref(dd, E);
28450  return(NULL);
28451  }
28452  neW = Cudd_Not(neW);
28453  }
28454  else {
28455  neW = cuddUniqueInterIVO(dd, v / 2, T, E);
28456  if (!neW) {
28457  Cudd_RecursiveDeref(dd, T);
28458  Cudd_RecursiveDeref(dd, E);
28459  return(NULL);
28460  }
28461  }
28462  Cudd_Ref(neW);
28463  Cudd_RecursiveDeref(dd, T);
28464  Cudd_RecursiveDeref(dd, E);
28465 
28466  cuddCacheInsert1(dd, cuddMakeBddFromZddCover, node, neW);
28467  Cudd_Deref(neW);
28468  return(neW);
28469 
28470 } /* end of cuddMakeBddFromZddCover */
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddInt.c:4371
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
DdNode * cuddCacheLookup1(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddInt.c:4591
DdNode * zero
Definition: cuddInt.h:330
#define Cudd_Regular(node)
Definition: cudd.h:373
int cuddZddGetCofactors3(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)
Definition: cuddInt.c:26127
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
void Cudd_Ref(DdNode *n)
Definition: cuddInt.c:14002
DdNode * cuddUniqueInterIVO(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20691
DdNode * one
Definition: cuddInt.h:329
#define Cudd_NotCond(node, c)
Definition: cudd.h:359
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void Cudd_Deref(DdNode *node)
Definition: cuddInt.c:14198
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633
DdNode * cuddMakeBddFromZddCover(DdManager *dd, DdNode *node)
Definition: cuddInt.c:28360

◆ cuddNextHigh()

int cuddNextHigh ( DdManager table,
int  x 
)

Function********************************************************************

Synopsis [Finds the next subtable with a larger index.]

Description [Finds the next subtable with a larger index. Returns the index.]

SideEffects [None]

SeeAlso [cuddNextLow]

Definition at line 15037 of file cuddInt.c.

15040 {
15041  return(x+1);
15042 
15043 } /* end of cuddNextHigh */

◆ cuddNextLow()

int cuddNextLow ( DdManager table,
int  x 
)

Function********************************************************************

Synopsis [Finds the next subtable with a smaller index.]

Description [Finds the next subtable with a smaller index. Returns the index.]

SideEffects [None]

SeeAlso [cuddNextHigh]

Definition at line 15059 of file cuddInt.c.

15062 {
15063  return(x-1);
15064 
15065 } /* end of cuddNextLow */

◆ cuddNodeArray()

DdNodePtr* cuddNodeArray ( DdNode f,
int *  n 
)

Function********************************************************************

Synopsis [Recursively collects all the nodes of a DD in an array.]

Description [Traverses the DD f and collects all its nodes in an array. The caller should free the array returned by cuddNodeArray. Returns a pointer to the array of nodes in case of success; NULL otherwise. The nodes are collected in reverse topological order, so that a node is always preceded in the array by all its descendants.]

SideEffects [The number of nodes is returned as a side effect.]

SeeAlso [Cudd_FirstNode]

Definition at line 23067 of file cuddInt.c.

23070 {
23071 DdNodePtr *table;
23072 int size, retval;
23073 
23074 size = ddDagInt(Cudd_Regular(f));
23075 table = ALLOC(DdNodePtr, size);
23076 if (table == NULL) {
23078 return(NULL);
23079 }
23080 
23081 retval = cuddNodeArrayRecur(f, table, 0);
23082 assert(retval == size);
23083 
23084 *n = size;
23085 return(table);
23086 
23087 } /* cuddNodeArray */
static int ddDagInt(DdNode *n)
Definition: cuddInt.c:23253
Definition: cudd.h:264
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:373
static void ddClearFlag(DdNode *f)
Definition: cuddInt.c:23821
#define ALLOC(type, num)
Definition: util.h:76
static int cuddNodeArrayRecur(DdNode *f, DdNodePtr *table, int index)
Definition: cuddInt.c:23288

◆ cuddNodeArrayRecur()

static int cuddNodeArrayRecur ( DdNode f,
DdNodePtr table,
int  index 
)
static

Function********************************************************************

Synopsis [Performs the recursive step of cuddNodeArray.]

Description [Performs the recursive step of cuddNodeArray. Returns an the number of nodes in the DD. Clear the least significant bit of the next field that was used as visited flag by cuddNodeArrayRecur when counting the nodes. node is supposed to be regular; the invariant is maintained by this procedure.]

SideEffects [None]

SeeAlso []

Definition at line 23288 of file cuddInt.c.

23292 {
23293 int tindex, eindex;
23294 
23295 if (!Cudd_IsComplement(f->next)) {
23296 return(index);
23297 }
23298 /* Clear visited flag. */
23299 f->next = Cudd_Regular(f->next);
23300 if (cuddIsConstant(f)) {
23301 table[index] = f;
23302 return(index + 1);
23303 }
23304 tindex = cuddNodeArrayRecur(cuddT(f), table, index);
23305 eindex = cuddNodeArrayRecur(Cudd_Regular(cuddE(f)), table, tindex);
23306 table[eindex] = f;
23307 return(eindex + 1);
23308 
23309 } /* end of cuddNodeArrayRecur */
#define Cudd_Regular(node)
Definition: cudd.h:373
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode * next
Definition: cudd.h:267
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddE(node)
Definition: cuddInt.h:625
static int cuddNodeArrayRecur(DdNode *f, DdNodePtr *table, int index)
Definition: cuddInt.c:23288

◆ cuddPrintNode()

void cuddPrintNode ( DdNode f,
FILE *  fp 
)

Function********************************************************************

Synopsis [Prints out information on a node.]

Description [Prints out information on a node.]

SideEffects [None]

SeeAlso []

Definition at line 5829 of file cuddInt.c.

5832 {
5833  f = Cudd_Regular(f);
5834 #if SIZEOF_VOID_P == 8
5835  (void) fprintf(fp," node 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f));
5836 #else
5837  (void) fprintf(fp," node 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",(ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f));
5838 #endif
5839 
5840 } /* end of cuddPrintNode */
DdHalfWord ref
Definition: cudd.h:266
#define Cudd_Regular(node)
Definition: cudd.h:373
#define cuddT(node)
Definition: cuddInt.h:609
unsigned int ptruint
Definition: cuddInt.h:250
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625

◆ cuddPrintVarGroups()

void cuddPrintVarGroups ( DdManager dd,
MtrNode root,
int  zdd,
int  silent 
)

Function********************************************************************

Synopsis [Prints the variable groups as a parenthesized list.]

Description [Prints the variable groups as a parenthesized list. For each group the level range that it represents is printed. After each group, the group's flags are printed, preceded by a `|'. For each flag (except MTR_TERMINAL) a character is printed.

  • F: MTR_FIXED
  • N: MTR_NEWNODE
  • S: MTR_SOFT

The second argument, silent, if different from 0, causes Cudd_PrintVarGroups to only check the syntax of the group tree.]

SideEffects [None]

SeeAlso []

Definition at line 5866 of file cuddInt.c.

5871 {
5872  MtrNode *node;
5873  int level;
5874 
5875  assert(root != NULL);
5876  assert(root->younger == NULL || root->younger->elder == root);
5877  assert(root->elder == NULL || root->elder->younger == root);
5878  if (zdd) {
5879  level = dd->permZ[root->index];
5880  } else {
5881  level = dd->perm[root->index];
5882  }
5883  if (!silent) (void) printf("(%d",level);
5884  if (MTR_TEST(root,MTR_TERMINAL) || root->child == NULL) {
5885  if (!silent) (void) printf(",");
5886  } else {
5887  node = root->child;
5888  while (node != NULL) {
5889  assert(node->low >= root->low && (int) (node->low + node->size) <= (int) (root->low + root->size));
5890  assert(node->parent == root);
5891  cuddPrintVarGroups(dd,node,zdd,silent);
5892  node = node->younger;
5893  }
5894  }
5895  if (!silent) {
5896  (void) printf("%d", (int) (level + root->size - 1));
5897  if (root->flags != MTR_DEFAULT) {
5898  (void) printf("|");
5899  if (MTR_TEST(root,MTR_FIXED)) (void) printf("F");
5900  if (MTR_TEST(root,MTR_NEWNODE)) (void) printf("N");
5901  if (MTR_TEST(root,MTR_SOFT)) (void) printf("S");
5902  }
5903  (void) printf(")");
5904  if (root->parent == NULL) (void) printf("\n");
5905  }
5906  assert((root->flags &~(MTR_TERMINAL | MTR_SOFT | MTR_FIXED | MTR_NEWNODE)) == 0);
5907  return;
5908 
5909 } /* end of cuddPrintVarGroups */
#define MTR_TERMINAL
Definition: mtr.h:95
MtrHalfWord flags
Definition: mtr.h:127
MtrHalfWord size
Definition: mtr.h:129
#define assert(ex)
Definition: util.h:141
#define MTR_FIXED
Definition: mtr.h:97
int * permZ
Definition: cuddInt.h:370
struct MtrNode * parent
Definition: mtr.h:131
#define MTR_DEFAULT
Definition: mtr.h:94
struct MtrNode * elder
Definition: mtr.h:133
#define MTR_TEST(node, flag)
Definition: mtr.h:150
struct MtrNode * younger
Definition: mtr.h:134
void cuddPrintVarGroups(DdManager *dd, MtrNode *root, int zdd, int silent)
Definition: cuddInt.c:5866
MtrHalfWord index
Definition: mtr.h:130
#define MTR_NEWNODE
Definition: mtr.h:98
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
struct MtrNode * child
Definition: mtr.h:132
int * perm
Definition: cuddInt.h:369
#define MTR_SOFT
Definition: mtr.h:96

◆ cuddReclaim()

void cuddReclaim ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Brings children of a dead node back.]

Description []

SideEffects [None]

SeeAlso [cuddReclaimZdd]

Definition at line 14223 of file cuddInt.c.

14226 {
14227  DdNode *N;
14228  int ord;
14229  DdNodePtr *stack = table->stack;
14230  int SP = 1;
14231  double initialDead = table->dead;
14232 
14233  N = Cudd_Regular(n);
14234 
14235 #ifdef DD_DEBUG
14236  assert(N->ref == 0);
14237 #endif
14238 
14239  do {
14240  if (N->ref == 0) {
14241  N->ref = 1;
14242  table->dead--;
14243  if (cuddIsConstant(N)) {
14244  table->constants.dead--;
14245  N = stack[--SP];
14246  } else {
14247  ord = table->perm[N->index];
14248  stack[SP++] = Cudd_Regular(cuddE(N));
14249  table->subtables[ord].dead--;
14250  N = cuddT(N);
14251  }
14252  } else {
14253  cuddSatInc(N->ref);
14254  N = stack[--SP];
14255  }
14256  } while (SP != 0);
14257 
14258  N = Cudd_Regular(n);
14259  cuddSatDec(N->ref);
14260  table->reclaimed += initialDead - table->dead;
14261 
14262 } /* end of cuddReclaim */
DdHalfWord ref
Definition: cudd.h:266
Definition: cudd.h:264
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:373
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode ** stack
Definition: cuddInt.h:364
unsigned int dead
Definition: cuddInt.h:355
unsigned int dead
Definition: cuddInt.h:316
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdSubtable constants
Definition: cuddInt.h:351
int * perm
Definition: cuddInt.h:369
#define cuddSatInc(x)
Definition: cuddInt.h:831
double reclaimed
Definition: cuddInt.h:367

◆ cuddReclaimZdd()

void cuddReclaimZdd ( DdManager table,
DdNode n 
)

Function********************************************************************

Synopsis [Brings children of a dead ZDD node back.]

Description []

SideEffects [None]

SeeAlso [cuddReclaim]

Definition at line 14277 of file cuddInt.c.

14280 {
14281  DdNode *N;
14282  int ord;
14283  DdNodePtr *stack = table->stack;
14284  int SP = 1;
14285 
14286  N = n;
14287 
14288 #ifdef DD_DEBUG
14289  assert(N->ref == 0);
14290 #endif
14291 
14292  do {
14293  cuddSatInc(N->ref);
14294 
14295  if (N->ref == 1) {
14296  table->deadZ--;
14297  table->reclaimed++;
14298 #ifdef DD_DEBUG
14299  assert(!cuddIsConstant(N));
14300 #endif
14301  ord = table->permZ[N->index];
14302  stack[SP++] = cuddE(N);
14303  table->subtableZ[ord].dead--;
14304  N = cuddT(N);
14305  } else {
14306  N = stack[--SP];
14307  }
14308  } while (SP != 0);
14309 
14310  cuddSatDec(n->ref);
14311 
14312 } /* end of cuddReclaimZdd */
DdHalfWord ref
Definition: cudd.h:266
Definition: cudd.h:264
unsigned int deadZ
Definition: cuddInt.h:356
#define assert(ex)
Definition: util.h:141
int * permZ
Definition: cuddInt.h:370
DdNode ** stack
Definition: cuddInt.h:364
unsigned int dead
Definition: cuddInt.h:316
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
#define cuddSatInc(x)
Definition: cuddInt.h:831
double reclaimed
Definition: cuddInt.h:367
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddRehash()

void cuddRehash ( DdManager unique,
int  i 
)

Function********************************************************************

Synopsis [Rehashes a unique subtable.]

Description [Doubles the size of a unique subtable and rehashes its contents.]

SideEffects [None]

SeeAlso []

Definition at line 20917 of file cuddInt.c.

20920 {
20921 unsigned int slots, oldslots;
20922 int shift, oldshift;
20923 int j, pos;
20924 DdNodePtr *nodelist, *oldnodelist;
20925 DdNode *node, *next;
20926 DdNode *sentinel = &(unique->sentinel);
20927 hack split;
20928 extern DD_OOMFP MMoutOfMemory;
20929 DD_OOMFP saveHandler;
20930 
20931 if (unique->gcFrac == DD_GC_FRAC_HI && unique->slots > unique->looseUpTo) {
20932 unique->gcFrac = DD_GC_FRAC_LO;
20933 unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots);
20934 #ifdef DD_VERBOSE
20935 (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_LO);
20936 (void) fprintf(unique->err,"minDead = %d\n", unique->minDead);
20937 #endif
20938 }
20939 
20940 if (unique->gcFrac != DD_GC_FRAC_MIN && unique->memused > unique->maxmem) {
20941 unique->gcFrac = DD_GC_FRAC_MIN;
20942 unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots);
20943 #ifdef DD_VERBOSE
20944 (void) fprintf(unique->err,"GC fraction = %.2f\t", DD_GC_FRAC_MIN);
20945 (void) fprintf(unique->err,"minDead = %d\n", unique->minDead);
20946 #endif
20947 cuddShrinkDeathRow(unique);
20948 if (cuddGarbageCollect(unique,1) > 0) return;
20949 }
20950 
20951 if (i != CUDD_CONST_INDEX) {
20952 oldslots = unique->subtables[i].slots;
20953 oldshift = unique->subtables[i].shift;
20954 oldnodelist = unique->subtables[i].nodelist;
20955 
20956 /* Compute the new size of the subtable. */
20957 slots = oldslots << 1;
20958 shift = oldshift - 1;
20959 
20960 saveHandler = MMoutOfMemory;
20961 MMoutOfMemory = Cudd_OutOfMem;
20962 nodelist = ALLOC(DdNodePtr, slots);
20963 MMoutOfMemory = saveHandler;
20964 if (nodelist == NULL) {
20965 (void) fprintf(unique->err,
20966 "Unable to resize subtable %d for lack of memory\n",
20967 i);
20968 /* Prevent frequent resizing attempts. */
20969 (void) cuddGarbageCollect(unique,1);
20970 if (unique->stash != NULL) {
20971 FREE(unique->stash);
20972 unique->stash = NULL;
20973 /* Inhibit resizing of tables. */
20974 cuddSlowTableGrowth(unique);
20975 }
20976 return;
20977 }
20978 unique->subtables[i].nodelist = nodelist;
20979 unique->subtables[i].slots = slots;
20980 unique->subtables[i].shift = shift;
20981 unique->subtables[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
20982 
20983 /* Move the nodes from the old table to the new table.
20984 ** This code depends on the type of hash function.
20985 ** It assumes that the effect of doubling the size of the table
20986 ** is to retain one more bit of the 32-bit hash value.
20987 ** The additional bit is the LSB. */
20988 for (j = 0; (unsigned) j < oldslots; j++) {
20989 DdNodePtr *evenP, *oddP;
20990 node = oldnodelist[j];
20991 evenP = &(nodelist[j<<1]);
20992 oddP = &(nodelist[(j<<1)+1]);
20993 while (node != sentinel) {
20994 next = node->next;
20995 pos = ddHash(cuddT(node), cuddE(node), shift);
20996 if (pos & 1) {
20997 *oddP = node;
20998 oddP = &(node->next);
20999 } else {
21000 *evenP = node;
21001 evenP = &(node->next);
21002 }
21003 node = next;
21004 }
21005 *evenP = *oddP = sentinel;
21006 }
21007 FREE(oldnodelist);
21008 
21009 #ifdef DD_VERBOSE
21010 (void) fprintf(unique->err,
21011 "rehashing layer %d: keys %d dead %d new size %d\n",
21012 i, unique->subtables[i].keys,
21013 unique->subtables[i].dead, slots);
21014 #endif
21015 } else {
21016 oldslots = unique->constants.slots;
21017 oldshift = unique->constants.shift;
21018 oldnodelist = unique->constants.nodelist;
21019 
21020 /* The constant subtable is never subjected to reordering.
21021 ** Therefore, when it is resized, it is because it has just
21022 ** reached the maximum load. We can safely just double the size,
21023 ** with no need for the loop we use for the other tables.
21024 */
21025 slots = oldslots << 1;
21026 shift = oldshift - 1;
21027 saveHandler = MMoutOfMemory;
21028 MMoutOfMemory = Cudd_OutOfMem;
21029 nodelist = ALLOC(DdNodePtr, slots);
21030 MMoutOfMemory = saveHandler;
21031 if (nodelist == NULL) {
21032 (void) fprintf(unique->err,
21033 "Unable to resize constant subtable for lack of memory\n");
21034 (void) cuddGarbageCollect(unique,1);
21035 for (j = 0; j < unique->size; j++) {
21036 unique->subtables[j].maxKeys <<= 1;
21037 }
21038 unique->constants.maxKeys <<= 1;
21039 return;
21040 }
21041 unique->constants.slots = slots;
21042 unique->constants.shift = shift;
21043 unique->constants.maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
21044 unique->constants.nodelist = nodelist;
21045 for (j = 0; (unsigned) j < slots; j++) {
21046 nodelist[j] = NULL;
21047 }
21048 for (j = 0; (unsigned) j < oldslots; j++) {
21049 node = oldnodelist[j];
21050 while (node != NULL) {
21051 next = node->next;
21052 split.value = cuddV(node);
21053 pos = ddHash(split.bits[0], split.bits[1], shift);
21054 node->next = nodelist[pos];
21055 nodelist[pos] = node;
21056 node = next;
21057 }
21058 }
21059 FREE(oldnodelist);
21060 
21061 #ifdef DD_VERBOSE
21062 (void) fprintf(unique->err,
21063 "rehashing constants: keys %d dead %d new size %d\n",
21064 unique->constants.keys,unique->constants.dead,slots);
21065 #endif
21066 }
21067 
21068 /* Update global data */
21069 
21070 unique->memused += (slots - oldslots) * sizeof(DdNodePtr);
21071 unique->slots += (slots - oldslots);
21072 ddFixLimits(unique);
21073 
21074 } /* end of cuddRehash */
unsigned int keys
Definition: cuddInt.h:314
#define ddHash(f, g, s)
Definition: cuddInt.h:696
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
void cuddShrinkDeathRow(DdManager *table)
Definition: cuddInt.c:14327
static DD_INLINE void ddFixLimits(DdManager *unique)
Definition: cuddInt.c:21624
unsigned int bits[2]
Definition: cuddInt.c:19539
int size
Definition: cuddInt.h:345
double gcFrac
Definition: cuddInt.h:359
unsigned int slots
Definition: cuddInt.h:352
FILE * err
Definition: cuddInt.h:424
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddInt.c:20120
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
void(* DD_OOMFP)(long)
Definition: cudd.h:300
#define cuddV(node)
Definition: cuddInt.h:641
#define DD_GC_FRAC_HI
Definition: cuddInt.h:135
DdNode sentinel
Definition: cuddInt.h:328
char * stash
Definition: cuddInt.h:382
void cuddSlowTableGrowth(DdManager *unique)
Definition: cuddInt.c:21237
#define ALLOC(type, num)
Definition: util.h:76
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:267
#define DD_GC_FRAC_LO
Definition: cuddInt.h:134
unsigned int maxKeys
Definition: cuddInt.h:315
#define CUDD_CONST_INDEX
Definition: cudd.h:107
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
CUDD_VALUE_TYPE value
Definition: cuddInt.c:19538
void(* MMoutOfMemory)(long)
Definition: util.c:105
#define DD_GC_FRAC_MIN
Definition: cuddInt.h:136
unsigned long memused
Definition: cuddInt.h:429
unsigned int looseUpTo
Definition: cuddInt.h:361
unsigned int slots
Definition: cuddInt.h:313
#define cuddE(node)
Definition: cuddInt.h:625
void Cudd_OutOfMem(long size)
Definition: cuddInt.c:22982
DdSubtable constants
Definition: cuddInt.h:351
unsigned long maxmem
Definition: cuddInt.h:430
int shift
Definition: cuddInt.h:312
unsigned int minDead
Definition: cuddInt.h:358

◆ cuddResizeLinear()

int cuddResizeLinear ( DdManager table)

Function********************************************************************

Synopsis [Resizes the linear transform matrix.]

Description [Resizes the linear transform matrix. Returns 1 if successful; 0 otherwise.]

SideEffects [none]

SeeAlso []

Definition at line 13314 of file cuddInt.c.

13316 {
13317  int words,oldWords;
13318  int wordsPerRow,oldWordsPerRow;
13319  int nvars,oldNvars;
13320  int word,oldWord;
13321  int bit;
13322  int i,j;
13323  long *linear,*oldLinear;
13324 
13325  oldNvars = table->linearSize;
13326  oldWordsPerRow = ((oldNvars - 1) >> LOGBPL) + 1;
13327  oldWords = oldWordsPerRow * oldNvars;
13328  oldLinear = table->linear;
13329 
13330  nvars = table->size;
13331  wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
13332  words = wordsPerRow * nvars;
13333  table->linear = linear = ALLOC(long,words);
13334  if (linear == NULL) {
13335  table->errorCode = CUDD_MEMORY_OUT;
13336  return(0);
13337  }
13338  table->memused += (words - oldWords) * sizeof(long);
13339  for (i = 0; i < words; i++) linear[i] = 0;
13340 
13341  /* Copy old matrix. */
13342  for (i = 0; i < oldNvars; i++) {
13343  for (j = 0; j < oldWordsPerRow; j++) {
13344  oldWord = oldWordsPerRow * i + j;
13345  word = wordsPerRow * i + j;
13346  linear[word] = oldLinear[oldWord];
13347  }
13348  }
13349  FREE(oldLinear);
13350 
13351  /* Add elements to the diagonal. */
13352  for (i = oldNvars; i < nvars; i++) {
13353  word = wordsPerRow * i + (i >> LOGBPL);
13354  bit = i & (BPL-1);
13355  linear[word] = 1 << bit;
13356  }
13357  table->linearSize = nvars;
13358 
13359  return(1);
13360 
13361 } /* end of cuddResizeLinear */
#define FREE(obj)
Definition: util.h:80
int size
Definition: cuddInt.h:345
#define BPL
Definition: cuddInt.c:12624
#define ALLOC(type, num)
Definition: util.h:76
long * linear
Definition: cuddInt.h:378
int linearSize
Definition: cuddInt.h:376
#define LOGBPL
Definition: cuddInt.c:12625
unsigned long memused
Definition: cuddInt.h:429
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddResizeTableZdd()

int cuddResizeTableZdd ( DdManager unique,
int  index 
)

Function********************************************************************

Synopsis [Increases the number of ZDD subtables in a unique table so that it meets or exceeds index.]

Description [Increases the number of ZDD subtables in a unique table so that it meets or exceeds index. When new ZDD variables are created, it is possible to preserve the functions unchanged, or it is possible to preserve the covers unchanged, but not both. cuddResizeTableZdd preserves the covers. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [ddResizeTable]

Definition at line 21093 of file cuddInt.c.

21096 {
21097 DdSubtable *newsubtables;
21098 DdNodePtr *newnodelist;
21099 int oldsize,newsize;
21100 int i,j,reorderSave;
21101 unsigned int numSlots = unique->initSlots;
21102 int *newperm, *newinvperm;
21103 
21104 oldsize = unique->sizeZ;
21105 /* Easy case: there is still room in the current table. */
21106 if (index < unique->maxSizeZ) {
21107 for (i = oldsize; i <= index; i++) {
21108 unique->subtableZ[i].slots = numSlots;
21109 unique->subtableZ[i].shift = sizeof(int) * 8 -
21110 cuddComputeFloorLog2(numSlots);
21111 unique->subtableZ[i].keys = 0;
21112 unique->subtableZ[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY;
21113 unique->subtableZ[i].dead = 0;
21114 unique->permZ[i] = i;
21115 unique->invpermZ[i] = i;
21116 newnodelist = unique->subtableZ[i].nodelist =
21117 ALLOC(DdNodePtr, numSlots);
21118 if (newnodelist == NULL) {
21119 unique->errorCode = CUDD_MEMORY_OUT;
21120 return(0);
21121 }
21122 for (j = 0; (unsigned) j < numSlots; j++) {
21123 newnodelist[j] = NULL;
21124 }
21125 }
21126 } else {
21127 /* The current table is too small: we need to allocate a new,
21128 ** larger one; move all old subtables, and initialize the new
21129 ** subtables up to index included.
21130 */
21131 newsize = index + DD_DEFAULT_RESIZE;
21132 #ifdef DD_VERBOSE
21133 (void) fprintf(unique->err,
21134 "Increasing the ZDD table size from %d to %d\n",
21135 unique->maxSizeZ, newsize);
21136 #endif
21137 newsubtables = ALLOC(DdSubtable,newsize);
21138 if (newsubtables == NULL) {
21139 unique->errorCode = CUDD_MEMORY_OUT;
21140 return(0);
21141 }
21142 newperm = ALLOC(int,newsize);
21143 if (newperm == NULL) {
21144 unique->errorCode = CUDD_MEMORY_OUT;
21145 return(0);
21146 }
21147 newinvperm = ALLOC(int,newsize);
21148 if (newinvperm == NULL) {
21149 unique->errorCode = CUDD_MEMORY_OUT;
21150 return(0);
21151 }
21152 unique->memused += (newsize - unique->maxSizeZ) * ((numSlots+1) *
21153 sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable));
21154 if (newsize > unique->maxSize) {
21155 FREE(unique->stack);
21156 unique->stack = ALLOC(DdNodePtr,newsize + 1);
21157 if (unique->stack == NULL) {
21158 unique->errorCode = CUDD_MEMORY_OUT;
21159 return(0);
21160 }
21161 unique->stack[0] = NULL; /* to suppress harmless UMR */
21162 unique->memused +=
21163 (newsize - ddMax(unique->maxSize,unique->maxSizeZ))
21164 * sizeof(DdNode *);
21165 }
21166 for (i = 0; i < oldsize; i++) {
21167 newsubtables[i].slots = unique->subtableZ[i].slots;
21168 newsubtables[i].shift = unique->subtableZ[i].shift;
21169 newsubtables[i].keys = unique->subtableZ[i].keys;
21170 newsubtables[i].maxKeys = unique->subtableZ[i].maxKeys;
21171 newsubtables[i].dead = unique->subtableZ[i].dead;
21172 newsubtables[i].nodelist = unique->subtableZ[i].nodelist;
21173 newperm[i] = unique->permZ[i];
21174 newinvperm[i] = unique->invpermZ[i];
21175 }
21176 for (i = oldsize; i <= index; i++) {
21177 newsubtables[i].slots = numSlots;
21178 newsubtables[i].shift = sizeof(int) * 8 -
21179 cuddComputeFloorLog2(numSlots);
21180 newsubtables[i].keys = 0;
21181 newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY;
21182 newsubtables[i].dead = 0;
21183 newperm[i] = i;
21184 newinvperm[i] = i;
21185 newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots);
21186 if (newnodelist == NULL) {
21187 unique->errorCode = CUDD_MEMORY_OUT;
21188 return(0);
21189 }
21190 for (j = 0; (unsigned) j < numSlots; j++) {
21191 newnodelist[j] = NULL;
21192 }
21193 }
21194 FREE(unique->subtableZ);
21195 unique->subtableZ = newsubtables;
21196 unique->maxSizeZ = newsize;
21197 FREE(unique->permZ);
21198 unique->permZ = newperm;
21199 FREE(unique->invpermZ);
21200 unique->invpermZ = newinvperm;
21201 }
21202 unique->slots += (index + 1 - unique->sizeZ) * numSlots;
21203 ddFixLimits(unique);
21204 unique->sizeZ = index + 1;
21205 
21206 /* Now that the table is in a coherent state, update the ZDD
21207 ** universe. We need to temporarily disable reordering,
21208 ** because we cannot reorder without universe in place.
21209 */
21210 
21211 reorderSave = unique->autoDynZ;
21212 unique->autoDynZ = 0;
21213 cuddZddFreeUniv(unique);
21214 if (!cuddZddInitUniv(unique)) {
21215 unique->autoDynZ = reorderSave;
21216 return(0);
21217 }
21218 unique->autoDynZ = reorderSave;
21219 
21220 return(1);
21221 
21222 } /* end of cuddResizeTableZdd */
unsigned int keys
Definition: cuddInt.h:314
int maxSizeZ
Definition: cuddInt.h:348
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
static DD_INLINE void ddFixLimits(DdManager *unique)
Definition: cuddInt.c:21624
int * invpermZ
Definition: cuddInt.h:372
unsigned int slots
Definition: cuddInt.h:352
FILE * err
Definition: cuddInt.h:424
int cuddZddInitUniv(DdManager *zdd)
Definition: cuddInt.c:10668
int * permZ
Definition: cuddInt.h:370
struct DdSubtable DdSubtable
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
DdNode ** stack
Definition: cuddInt.h:364
unsigned int initSlots
Definition: cuddInt.h:363
#define ALLOC(type, num)
Definition: util.h:76
unsigned int dead
Definition: cuddInt.h:316
int maxSize
Definition: cuddInt.h:347
unsigned int maxKeys
Definition: cuddInt.h:315
#define ddMax(x, y)
Definition: cuddInt.h:785
DdNode ** nodelist
Definition: cuddInt.h:311
unsigned long memused
Definition: cuddInt.h:429
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddInt.c:5102
#define DD_DEFAULT_RESIZE
Definition: cuddInt.h:103
int sizeZ
Definition: cuddInt.h:346
unsigned int slots
Definition: cuddInt.h:313
int autoDynZ
Definition: cuddInt.h:401
int shift
Definition: cuddInt.h:312
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:350
void cuddZddFreeUniv(DdManager *zdd)
Definition: cuddInt.c:10717

◆ cuddSetInteract()

void cuddSetInteract ( DdManager table,
int  x,
int  y 
)

AutomaticEnd Function********************************************************************

Synopsis [Set interaction matrix entries.]

Description [Given a pair of variables 0 <= x < y < table->size, sets the corresponding bit of the interaction matrix to 1.]

SideEffects [None]

SeeAlso []

Definition at line 10882 of file cuddInt.c.

10886 {
10887  int posn, word, bit;
10888 
10889 #ifdef DD_DEBUG
10890  assert(x < y);
10891  assert(y < table->size);
10892  assert(x >= 0);
10893 #endif
10894 
10895  posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1;
10896  word = posn >> LOGBPL;
10897  bit = posn & (BPL-1);
10898  table->interact[word] |= 1L << bit;
10899 
10900 } /* end of cuddSetInteract */
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
#define BPL
Definition: cuddInt.c:12624
long * interact
Definition: cuddInt.h:377
#define LOGBPL
Definition: cuddInt.c:12625

◆ cuddShrinkDeathRow()

void cuddShrinkDeathRow ( DdManager table)

Function********************************************************************

Synopsis [Shrinks the death row.]

Description [Shrinks the death row by a factor of four.]

SideEffects [None]

SeeAlso [cuddClearDeathRow]

Definition at line 14327 of file cuddInt.c.

14329 {
14330 #ifndef DD_NO_DEATH_ROW
14331  int i;
14332 
14333  if (table->deathRowDepth > 3) {
14334  for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) {
14335  if (table->deathRow[i] == NULL) break;
14336  Cudd_IterDerefBdd(table,table->deathRow[i]);
14337  table->deathRow[i] = NULL;
14338  }
14339  table->deathRowDepth /= 4;
14340  table->deadMask = table->deathRowDepth - 1;
14341  if ((unsigned) table->nextDead > table->deadMask) {
14342  table->nextDead = 0;
14343  }
14344  table->deathRow = REALLOC(DdNodePtr, table->deathRow,
14345  table->deathRowDepth);
14346  }
14347 #endif
14348 
14349 } /* end of cuddShrinkDeathRow */
Definition: cudd.h:264
unsigned deadMask
Definition: cuddInt.h:387
DdNode ** deathRow
Definition: cuddInt.h:384
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14090
int nextDead
Definition: cuddInt.h:386
int deathRowDepth
Definition: cuddInt.h:385
#define REALLOC(type, obj, num)
Definition: util.h:78

◆ cuddSifting()

int cuddSifting ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [Implementation of Rudell's sifting algorithm.]

Description [Implementation of Rudell's sifting algorithm. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique table.
  2. Sift the variable up and down, remembering each time the total size of the DD heap.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 14824 of file cuddInt.c.

14828 {
14829  int i;
14830  int *var;
14831  int size;
14832  int x;
14833  int result;
14834 #ifdef DD_STATS
14835  int previousSize;
14836 #endif
14837 
14838  size = table->size;
14839 
14840  /* Find order in which to sift variables. */
14841  var = NULL;
14842  entry = ALLOC(int,size);
14843  if (entry == NULL) {
14844  table->errorCode = CUDD_MEMORY_OUT;
14845  goto cuddSiftingOutOfMem;
14846  }
14847  var = ALLOC(int,size);
14848  if (var == NULL) {
14849  table->errorCode = CUDD_MEMORY_OUT;
14850  goto cuddSiftingOutOfMem;
14851  }
14852 
14853  for (i = 0; i < size; i++) {
14854  x = table->perm[i];
14855  entry[i] = table->subtables[x].keys;
14856  var[i] = i;
14857  }
14858 
14859  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddUniqueCompare);
14860 
14861  /* Now sift. */
14862  for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
14863  if (ddTotalNumberSwapping >= table->siftMaxSwap)
14864  break;
14865  if (util_cpu_time() - table->startTime + table->reordTime
14866  > table->timeLimit) {
14867  table->autoDyn = 0; /* prevent further reordering */
14868  break;
14869  }
14870  x = table->perm[var[i]];
14871 
14872  if (x < lower || x > upper || table->subtables[x].bindVar == 1)
14873  continue;
14874 #ifdef DD_STATS
14875  previousSize = table->keys - table->isolated;
14876 #endif
14877  result = ddSiftingAux(table, x, lower, upper);
14878  if (!result) goto cuddSiftingOutOfMem;
14879 #ifdef DD_STATS
14880  if (table->keys < (unsigned) previousSize + table->isolated) {
14881  (void) fprintf(table->out,"-");
14882  } else if (table->keys > (unsigned) previousSize + table->isolated) {
14883  (void) fprintf(table->out,"+"); /* should never happen */
14884  (void) fprintf(table->err,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keys - table->isolated, var[i]);
14885  } else {
14886  (void) fprintf(table->out,"=");
14887  }
14888  fflush(table->out);
14889 #endif
14890  }
14891 
14892  FREE(var);
14893  FREE(entry);
14894 
14895  return(1);
14896 
14897  cuddSiftingOutOfMem:
14898 
14899  if (entry != NULL) FREE(entry);
14900  if (var != NULL) FREE(var);
14901 
14902  return(0);
14903 
14904 } /* end of cuddSifting */
unsigned int keys
Definition: cuddInt.h:314
unsigned long reordTime
Definition: cuddInt.h:434
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:302
unsigned long startTime
Definition: cuddInt.h:426
int size
Definition: cuddInt.h:345
static int ddUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddInt.c:15644
FILE * err
Definition: cuddInt.h:424
int bindVar
Definition: cuddInt.h:318
DdSubtable * subtables
Definition: cuddInt.h:349
static int ddSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddInt.c:15809
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: util.c:34
int siftMaxVar
Definition: cuddInt.h:395
static int result
Definition: cuddInt.c:7466
static int * entry
Definition: cuddInt.c:8422
int isolated
Definition: cuddInt.h:368
int ddTotalNumberSwapping
Definition: cuddInt.c:14489
int autoDyn
Definition: cuddInt.h:400
int * perm
Definition: cuddInt.h:369
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddSlowTableGrowth()

void cuddSlowTableGrowth ( DdManager unique)

Function********************************************************************

Synopsis [Adjusts parameters of a table to slow down its growth.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 21237 of file cuddInt.c.

21239 {
21240 int i;
21241 
21242 unique->maxCacheHard = unique->cacheSlots - 1;
21243 unique->cacheSlack = - (int) (unique->cacheSlots + 1);
21244 for (i = 0; i < unique->size; i++) {
21245 unique->subtables[i].maxKeys <<= 2;
21246 }
21247 unique->gcFrac = DD_GC_FRAC_MIN;
21248 unique->minDead = (unsigned) (DD_GC_FRAC_MIN * (double) unique->slots);
21249 cuddShrinkDeathRow(unique);
21250 (void) fprintf(unique->err,"Slowing down table growth: ");
21251 (void) fprintf(unique->err,"GC fraction = %.2f\t", unique->gcFrac);
21252 (void) fprintf(unique->err,"minDead = %u\n", unique->minDead);
21253 
21254 } /* end of cuddSlowTableGrowth */
void cuddShrinkDeathRow(DdManager *table)
Definition: cuddInt.c:14327
int size
Definition: cuddInt.h:345
double gcFrac
Definition: cuddInt.h:359
unsigned int maxCacheHard
Definition: cuddInt.h:343
unsigned int slots
Definition: cuddInt.h:352
FILE * err
Definition: cuddInt.h:424
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int cacheSlots
Definition: cuddInt.h:337
unsigned int maxKeys
Definition: cuddInt.h:315
int cacheSlack
Definition: cuddInt.h:342
#define DD_GC_FRAC_MIN
Definition: cuddInt.h:136
unsigned int minDead
Definition: cuddInt.h:358

◆ cuddSwapInPlace()

int cuddSwapInPlace ( DdManager table,
int  x,
int  y 
)

Function********************************************************************

Synopsis [Swaps two adjacent variables.]

Description [Swaps two adjacent variables. It assumes that no dead nodes are present on entry to this procedure. The procedure then guarantees that no dead nodes will be present when it terminates. cuddSwapInPlace assumes that x < y. Returns the number of keys in the table if successful; 0 otherwise.]

SideEffects [None]

Definition at line 15082 of file cuddInt.c.

15086 {
15087  DdNodePtr *xlist, *ylist;
15088  int xindex, yindex;
15089  int xslots, yslots;
15090  int xshift, yshift;
15091  int oldxkeys, oldykeys;
15092  int newxkeys, newykeys;
15093  int comple, newcomplement;
15094  int i;
15095  Cudd_VariableType varType;
15096  Cudd_LazyGroupType groupType;
15097  int posn;
15098  int isolated;
15099  DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10,*newf1,*newf0;
15100  DdNode *g,*next;
15101  DdNodePtr *previousP;
15102  DdNode *tmp;
15103  DdNode *sentinel = &(table->sentinel);
15104  extern DD_OOMFP MMoutOfMemory;
15105  DD_OOMFP saveHandler;
15106 
15107 #ifdef DD_DEBUG
15108  int count,idcheck;
15109 #endif
15110 
15111 #ifdef DD_DEBUG
15112  assert(x < y);
15113  assert(cuddNextHigh(table,x) == y);
15114  assert(table->subtables[x].keys != 0);
15115  assert(table->subtables[y].keys != 0);
15116  assert(table->subtables[x].dead == 0);
15117  assert(table->subtables[y].dead == 0);
15118 #endif
15119 
15121 
15122  /* Get parameters of x subtable. */
15123  xindex = table->invperm[x];
15124  xlist = table->subtables[x].nodelist;
15125  oldxkeys = table->subtables[x].keys;
15126  xslots = table->subtables[x].slots;
15127  xshift = table->subtables[x].shift;
15128 
15129  /* Get parameters of y subtable. */
15130  yindex = table->invperm[y];
15131  ylist = table->subtables[y].nodelist;
15132  oldykeys = table->subtables[y].keys;
15133  yslots = table->subtables[y].slots;
15134  yshift = table->subtables[y].shift;
15135 
15136  if (!cuddTestInteract(table,xindex,yindex)) {
15137 #ifdef DD_STATS
15138  ddTotalNISwaps++;
15139 #endif
15140  newxkeys = oldxkeys;
15141  newykeys = oldykeys;
15142  } else {
15143  newxkeys = 0;
15144  newykeys = oldykeys;
15145 
15146  /* Check whether the two projection functions involved in this
15147  ** swap are isolated. At the end, we'll be able to tell how many
15148  ** isolated projection functions are there by checking only these
15149  ** two functions again. This is done to eliminate the isolated
15150  ** projection functions from the node count.
15151  */
15152  isolated = - ((table->vars[xindex]->ref == 1) +
15153  (table->vars[yindex]->ref == 1));
15154 
15155  /* The nodes in the x layer that do not depend on
15156  ** y will stay there; the others are put in a chain.
15157  ** The chain is handled as a LIFO; g points to the beginning.
15158  */
15159  g = NULL;
15160  if ((oldxkeys >= xslots || (unsigned) xslots == table->initSlots) &&
15161  oldxkeys <= DD_MAX_SUBTABLE_DENSITY * xslots) {
15162  for (i = 0; i < xslots; i++) {
15163  previousP = &(xlist[i]);
15164  f = *previousP;
15165  while (f != sentinel) {
15166  next = f->next;
15167  f1 = cuddT(f); f0 = cuddE(f);
15168  if (f1->index != (DdHalfWord) yindex &&
15169  Cudd_Regular(f0)->index != (DdHalfWord) yindex) {
15170  /* stays */
15171  newxkeys++;
15172  *previousP = f;
15173  previousP = &(f->next);
15174  } else {
15175  f->index = yindex;
15176  f->next = g;
15177  g = f;
15178  }
15179  f = next;
15180  } /* while there are elements in the collision chain */
15181  *previousP = sentinel;
15182  } /* for each slot of the x subtable */
15183  } else { /* resize xlist */
15184  DdNode *h = NULL;
15185  DdNodePtr *newxlist;
15186  unsigned int newxslots;
15187  int newxshift;
15188  /* Empty current xlist. Nodes that stay go to list h;
15189  ** nodes that move go to list g. */
15190  for (i = 0; i < xslots; i++) {
15191  f = xlist[i];
15192  while (f != sentinel) {
15193  next = f->next;
15194  f1 = cuddT(f); f0 = cuddE(f);
15195  if (f1->index != (DdHalfWord) yindex &&
15196  Cudd_Regular(f0)->index != (DdHalfWord) yindex) {
15197  /* stays */
15198  f->next = h;
15199  h = f;
15200  newxkeys++;
15201  } else {
15202  f->index = yindex;
15203  f->next = g;
15204  g = f;
15205  }
15206  f = next;
15207  } /* while there are elements in the collision chain */
15208  } /* for each slot of the x subtable */
15209  /* Decide size of new subtable. */
15210  newxshift = xshift;
15211  newxslots = xslots;
15212  while ((unsigned) oldxkeys > DD_MAX_SUBTABLE_DENSITY * newxslots) {
15213  newxshift--;
15214  newxslots <<= 1;
15215  }
15216  while ((unsigned) oldxkeys < newxslots &&
15217  newxslots > table->initSlots) {
15218  newxshift++;
15219  newxslots >>= 1;
15220  }
15221  /* Try to allocate new table. Be ready to back off. */
15222  saveHandler = MMoutOfMemory;
15223  MMoutOfMemory = Cudd_OutOfMem;
15224  newxlist = ALLOC(DdNodePtr, newxslots);
15225  MMoutOfMemory = saveHandler;
15226  if (newxlist == NULL) {
15227  (void) fprintf(table->err, "Unable to resize subtable %d for lack of memory\n", i);
15228  newxlist = xlist;
15229  newxslots = xslots;
15230  newxshift = xshift;
15231  } else {
15232  table->slots += ((int) newxslots - xslots);
15233  table->minDead = (unsigned)
15234  (table->gcFrac * (double) table->slots);
15235  table->cacheSlack = (int)
15237  * table->slots) - 2 * (int) table->cacheSlots;
15238  table->memused +=
15239  ((int) newxslots - xslots) * sizeof(DdNodePtr);
15240  FREE(xlist);
15241  xslots = newxslots;
15242  xshift = newxshift;
15243  xlist = newxlist;
15244  }
15245  /* Initialize new subtable. */
15246  for (i = 0; i < xslots; i++) {
15247  xlist[i] = sentinel;
15248  }
15249  /* Move nodes that were parked in list h to their new home. */
15250  f = h;
15251  while (f != NULL) {
15252  next = f->next;
15253  f1 = cuddT(f);
15254  f0 = cuddE(f);
15255  /* Check xlist for pair (f11,f01). */
15256  posn = ddHash(f1, f0, xshift);
15257  /* For each element tmp in collision list xlist[posn]. */
15258  previousP = &(xlist[posn]);
15259  tmp = *previousP;
15260  while (f1 < cuddT(tmp)) {
15261  previousP = &(tmp->next);
15262  tmp = *previousP;
15263  }
15264  while (f1 == cuddT(tmp) && f0 < cuddE(tmp)) {
15265  previousP = &(tmp->next);
15266  tmp = *previousP;
15267  }
15268  f->next = *previousP;
15269  *previousP = f;
15270  f = next;
15271  }
15272  }
15273 
15274 #ifdef DD_COUNT
15275  table->swapSteps += oldxkeys - newxkeys;
15276 #endif
15277  /* Take care of the x nodes that must be re-expressed.
15278  ** They form a linked list pointed by g. Their index has been
15279  ** already changed to yindex.
15280  */
15281  f = g;
15282  while (f != NULL) {
15283  next = f->next;
15284  /* Find f1, f0, f11, f10, f01, f00. */
15285  f1 = cuddT(f);
15286 #ifdef DD_DEBUG
15287  assert(!(Cudd_IsComplement(f1)));
15288 #endif
15289  if ((int) f1->index == yindex) {
15290  f11 = cuddT(f1); f10 = cuddE(f1);
15291  } else {
15292  f11 = f10 = f1;
15293  }
15294 #ifdef DD_DEBUG
15295  assert(!(Cudd_IsComplement(f11)));
15296 #endif
15297  f0 = cuddE(f);
15298  comple = Cudd_IsComplement(f0);
15299  f0 = Cudd_Regular(f0);
15300  if ((int) f0->index == yindex) {
15301  f01 = cuddT(f0); f00 = cuddE(f0);
15302  } else {
15303  f01 = f00 = f0;
15304  }
15305  if (comple) {
15306  f01 = Cudd_Not(f01);
15307  f00 = Cudd_Not(f00);
15308  }
15309  /* Decrease ref count of f1. */
15310  cuddSatDec(f1->ref);
15311  /* Create the new T child. */
15312  if (f11 == f01) {
15313  newf1 = f11;
15314  cuddSatInc(newf1->ref);
15315  } else {
15316  /* Check xlist for triple (xindex,f11,f01). */
15317  posn = ddHash(f11, f01, xshift);
15318  /* For each element newf1 in collision list xlist[posn]. */
15319  previousP = &(xlist[posn]);
15320  newf1 = *previousP;
15321  while (f11 < cuddT(newf1)) {
15322  previousP = &(newf1->next);
15323  newf1 = *previousP;
15324  }
15325  while (f11 == cuddT(newf1) && f01 < cuddE(newf1)) {
15326  previousP = &(newf1->next);
15327  newf1 = *previousP;
15328  }
15329  if (cuddT(newf1) == f11 && cuddE(newf1) == f01) {
15330  cuddSatInc(newf1->ref);
15331  } else { /* no match */
15332  newf1 = cuddDynamicAllocNode(table);
15333  if (newf1 == NULL)
15334  goto cuddSwapOutOfMem;
15335  newf1->index = xindex; newf1->ref = 1;
15336  cuddT(newf1) = f11;
15337  cuddE(newf1) = f01;
15338  /* Insert newf1 in the collision list xlist[posn];
15339  ** increase the ref counts of f11 and f01.
15340  */
15341  newxkeys++;
15342  newf1->next = *previousP;
15343  *previousP = newf1;
15344  cuddSatInc(f11->ref);
15345  tmp = Cudd_Regular(f01);
15346  cuddSatInc(tmp->ref);
15347  }
15348  }
15349  cuddT(f) = newf1;
15350 #ifdef DD_DEBUG
15351  assert(!(Cudd_IsComplement(newf1)));
15352 #endif
15353 
15354  /* Do the same for f0, keeping complement dots into account. */
15355  /* Decrease ref count of f0. */
15356  tmp = Cudd_Regular(f0);
15357  cuddSatDec(tmp->ref);
15358  /* Create the new E child. */
15359  if (f10 == f00) {
15360  newf0 = f00;
15361  tmp = Cudd_Regular(newf0);
15362  cuddSatInc(tmp->ref);
15363  } else {
15364  /* make sure f10 is regular */
15365  newcomplement = Cudd_IsComplement(f10);
15366  if (newcomplement) {
15367  f10 = Cudd_Not(f10);
15368  f00 = Cudd_Not(f00);
15369  }
15370  /* Check xlist for triple (xindex,f10,f00). */
15371  posn = ddHash(f10, f00, xshift);
15372  /* For each element newf0 in collision list xlist[posn]. */
15373  previousP = &(xlist[posn]);
15374  newf0 = *previousP;
15375  while (f10 < cuddT(newf0)) {
15376  previousP = &(newf0->next);
15377  newf0 = *previousP;
15378  }
15379  while (f10 == cuddT(newf0) && f00 < cuddE(newf0)) {
15380  previousP = &(newf0->next);
15381  newf0 = *previousP;
15382  }
15383  if (cuddT(newf0) == f10 && cuddE(newf0) == f00) {
15384  cuddSatInc(newf0->ref);
15385  } else { /* no match */
15386  newf0 = cuddDynamicAllocNode(table);
15387  if (newf0 == NULL)
15388  goto cuddSwapOutOfMem;
15389  newf0->index = xindex; newf0->ref = 1;
15390  cuddT(newf0) = f10;
15391  cuddE(newf0) = f00;
15392  /* Insert newf0 in the collision list xlist[posn];
15393  ** increase the ref counts of f10 and f00.
15394  */
15395  newxkeys++;
15396  newf0->next = *previousP;
15397  *previousP = newf0;
15398  cuddSatInc(f10->ref);
15399  tmp = Cudd_Regular(f00);
15400  cuddSatInc(tmp->ref);
15401  }
15402  if (newcomplement) {
15403  newf0 = Cudd_Not(newf0);
15404  }
15405  }
15406  cuddE(f) = newf0;
15407 
15408  /* Insert the modified f in ylist.
15409  ** The modified f does not already exists in ylist.
15410  ** (Because of the uniqueness of the cofactors.)
15411  */
15412  posn = ddHash(newf1, newf0, yshift);
15413  newykeys++;
15414  previousP = &(ylist[posn]);
15415  tmp = *previousP;
15416  while (newf1 < cuddT(tmp)) {
15417  previousP = &(tmp->next);
15418  tmp = *previousP;
15419  }
15420  while (newf1 == cuddT(tmp) && newf0 < cuddE(tmp)) {
15421  previousP = &(tmp->next);
15422  tmp = *previousP;
15423  }
15424  f->next = *previousP;
15425  *previousP = f;
15426  f = next;
15427  } /* while f != NULL */
15428 
15429  /* GC the y layer. */
15430 
15431  /* For each node f in ylist. */
15432  for (i = 0; i < yslots; i++) {
15433  previousP = &(ylist[i]);
15434  f = *previousP;
15435  while (f != sentinel) {
15436  next = f->next;
15437  if (f->ref == 0) {
15438  tmp = cuddT(f);
15439  cuddSatDec(tmp->ref);
15440  tmp = Cudd_Regular(cuddE(f));
15441  cuddSatDec(tmp->ref);
15442  cuddDeallocNode(table,f);
15443  newykeys--;
15444  } else {
15445  *previousP = f;
15446  previousP = &(f->next);
15447  }
15448  f = next;
15449  } /* while f */
15450  *previousP = sentinel;
15451  } /* for i */
15452 
15453 #ifdef DD_DEBUG
15454  #if 0
15455  (void) fprintf(table->out,"Swapping %d and %d\n",x,y);
15456 #endif
15457  count = 0;
15458  idcheck = 0;
15459  for (i = 0; i < yslots; i++) {
15460  f = ylist[i];
15461  while (f != sentinel) {
15462  count++;
15463  if (f->index != (DdHalfWord) yindex)
15464  idcheck++;
15465  f = f->next;
15466  }
15467  }
15468  if (count != newykeys) {
15469  (void) fprintf(table->out,
15470  "Error in finding newykeys\toldykeys = %d\tnewykeys = %d\tactual = %d\n",
15471  oldykeys,newykeys,count);
15472  }
15473  if (idcheck != 0)
15474  (void) fprintf(table->out,
15475  "Error in id's of ylist\twrong id's = %d\n",
15476  idcheck);
15477  count = 0;
15478  idcheck = 0;
15479  for (i = 0; i < xslots; i++) {
15480  f = xlist[i];
15481  while (f != sentinel) {
15482  count++;
15483  if (f->index != (DdHalfWord) xindex)
15484  idcheck++;
15485  f = f->next;
15486  }
15487  }
15488  if (count != newxkeys) {
15489  (void) fprintf(table->out,
15490  "Error in finding newxkeys\toldxkeys = %d \tnewxkeys = %d \tactual = %d\n",
15491  oldxkeys,newxkeys,count);
15492  }
15493  if (idcheck != 0)
15494  (void) fprintf(table->out,
15495  "Error in id's of xlist\twrong id's = %d\n",
15496  idcheck);
15497 #endif
15498 
15499  isolated += (table->vars[xindex]->ref == 1) +
15500  (table->vars[yindex]->ref == 1);
15501  table->isolated += isolated;
15502  }
15503 
15504  /* Set the appropriate fields in table. */
15505  table->subtables[x].nodelist = ylist;
15506  table->subtables[x].slots = yslots;
15507  table->subtables[x].shift = yshift;
15508  table->subtables[x].keys = newykeys;
15509  table->subtables[x].maxKeys = yslots * DD_MAX_SUBTABLE_DENSITY;
15510  i = table->subtables[x].bindVar;
15511  table->subtables[x].bindVar = table->subtables[y].bindVar;
15512  table->subtables[y].bindVar = i;
15513  /* Adjust filds for lazy sifting. */
15514  varType = table->subtables[x].varType;
15515  table->subtables[x].varType = table->subtables[y].varType;
15516  table->subtables[y].varType = varType;
15517  i = table->subtables[x].pairIndex;
15518  table->subtables[x].pairIndex = table->subtables[y].pairIndex;
15519  table->subtables[y].pairIndex = i;
15520  i = table->subtables[x].varHandled;
15521  table->subtables[x].varHandled = table->subtables[y].varHandled;
15522  table->subtables[y].varHandled = i;
15523  groupType = table->subtables[x].varToBeGrouped;
15524  table->subtables[x].varToBeGrouped = table->subtables[y].varToBeGrouped;
15525  table->subtables[y].varToBeGrouped = groupType;
15526 
15527  table->subtables[y].nodelist = xlist;
15528  table->subtables[y].slots = xslots;
15529  table->subtables[y].shift = xshift;
15530  table->subtables[y].keys = newxkeys;
15531  table->subtables[y].maxKeys = xslots * DD_MAX_SUBTABLE_DENSITY;
15532 
15533  table->perm[xindex] = y; table->perm[yindex] = x;
15534  table->invperm[x] = yindex; table->invperm[y] = xindex;
15535 
15536  table->keys += newxkeys + newykeys - oldxkeys - oldykeys;
15537 
15538  return(table->keys - table->isolated);
15539 
15540  cuddSwapOutOfMem:
15541  (void) fprintf(table->err,"Error: cuddSwapInPlace out of memory\n");
15542 
15543  return (0);
15544 
15545 } /* end of cuddSwapInPlace */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
unsigned short DdHalfWord
Definition: cudd.h:253
#define ddHash(f, g, s)
Definition: cuddInt.h:696
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define FREE(obj)
Definition: util.h:80
#define assert(ex)
Definition: util.h:141
double gcFrac
Definition: cuddInt.h:359
unsigned int maxCacheHard
Definition: cuddInt.h:343
unsigned int slots
Definition: cuddInt.h:352
#define Cudd_Regular(node)
Definition: cudd.h:373
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
FILE * err
Definition: cuddInt.h:424
int bindVar
Definition: cuddInt.h:318
DdSubtable * subtables
Definition: cuddInt.h:349
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
void(* DD_OOMFP)(long)
Definition: cudd.h:300
Cudd_VariableType
Definition: cudd.h:243
unsigned int initSlots
Definition: cuddInt.h:363
Cudd_VariableType varType
Definition: cuddInt.h:320
unsigned int cacheSlots
Definition: cuddInt.h:337
#define Cudd_IsComplement(node)
Definition: cudd.h:401
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
DdNode sentinel
Definition: cuddInt.h:328
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
unsigned int dead
Definition: cuddInt.h:316
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:267
Cudd_LazyGroupType varToBeGrouped
Definition: cuddInt.h:323
unsigned int maxKeys
Definition: cuddInt.h:315
DdNode ** nodelist
Definition: cuddInt.h:311
#define ddMin(x, y)
Definition: cuddInt.h:771
#define DD_MAX_CACHE_TO_SLOTS_RATIO
Definition: cuddInt.h:145
int cacheSlack
Definition: cuddInt.h:342
#define cuddT(node)
Definition: cuddInt.h:609
void(* MMoutOfMemory)(long)
Definition: util.c:105
int varHandled
Definition: cuddInt.h:322
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:520
unsigned long memused
Definition: cuddInt.h:429
DdHalfWord index
Definition: cudd.h:265
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
int pairIndex
Definition: cuddInt.h:321
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917
void Cudd_OutOfMem(long size)
Definition: cuddInt.c:22982
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int ddTotalNumberSwapping
Definition: cuddInt.c:14489
int shift
Definition: cuddInt.h:312
Cudd_LazyGroupType
Definition: cudd.h:228
int * perm
Definition: cuddInt.h:369
unsigned int minDead
Definition: cuddInt.h:358
#define cuddSatInc(x)
Definition: cuddInt.h:831

◆ cuddSwapping()

int cuddSwapping ( DdManager table,
int  lower,
int  upper,
Cudd_ReorderingType  heuristic 
)

Function********************************************************************

Synopsis [Reorders variables by a sequence of (non-adjacent) swaps.]

Description [Implementation of Plessier's algorithm that reorders variables by a sequence of (non-adjacent) swaps.

  1. Select two variables (RANDOM or HEURISTIC).
  2. Permute these variables.
  3. If the nodes have decreased accept the permutation.
  4. Otherwise reconstruct the original heap.
  5. Loop.

Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 14926 of file cuddInt.c.

14931 {
14932  int i, j;
14933  int max, keys;
14934  int nvars;
14935  int x, y;
14936  int iterate;
14937  int previousSize;
14938  Move *moves, *move;
14939  int pivot;
14940  int modulo;
14941  int result;
14942 
14943 #ifdef DD_DEBUG
14944  /* Sanity check */
14945  assert(lower >= 0 && upper < table->size && lower <= upper);
14946 #endif
14947 
14948  nvars = upper - lower + 1;
14949  iterate = nvars;
14950 
14951  for (i = 0; i < iterate; i++) {
14952  if (ddTotalNumberSwapping >= table->siftMaxSwap)
14953  break;
14954  if (heuristic == CUDD_REORDER_RANDOM_PIVOT) {
14955  max = -1;
14956  for (j = lower; j <= upper; j++) {
14957  if ((keys = table->subtables[j].keys) > max) {
14958  max = keys;
14959  pivot = j;
14960  }
14961  }
14962 
14963  modulo = upper - pivot;
14964  if (modulo == 0) {
14965  y = pivot;
14966  } else{
14967  y = pivot + 1 + ((int) Cudd_Random() % modulo);
14968  }
14969 
14970  modulo = pivot - lower - 1;
14971  if (modulo < 1) {
14972  x = lower;
14973  } else{
14974  do {
14975  x = (int) Cudd_Random() % modulo;
14976  } while (x == y);
14977  }
14978  } else {
14979  x = ((int) Cudd_Random() % nvars) + lower;
14980  do {
14981  y = ((int) Cudd_Random() % nvars) + lower;
14982  } while (x == y);
14983  }
14984  previousSize = table->keys - table->isolated;
14985  moves = ddSwapAny(table,x,y);
14986  if (moves == NULL) goto cuddSwappingOutOfMem;
14987  result = ddSiftingBackward(table,previousSize,moves);
14988  if (!result) goto cuddSwappingOutOfMem;
14989  while (moves != NULL) {
14990  move = moves->next;
14991  cuddDeallocMove(table, moves);
14992  moves = move;
14993  }
14994 #ifdef DD_STATS
14995  if (table->keys < (unsigned) previousSize + table->isolated) {
14996  (void) fprintf(table->out,"-");
14997  } else if (table->keys > (unsigned) previousSize + table->isolated) {
14998  (void) fprintf(table->out,"+"); /* should never happen */
14999  } else {
15000  (void) fprintf(table->out,"=");
15001  }
15002  fflush(table->out);
15003 #endif
15004 #if 0
15005  (void) fprintf(table->out,"#:t_SWAPPING %8d: tmp size\n",
15006  table->keys - table->isolated);
15007 #endif
15008  }
15009 
15010  return(1);
15011 
15012  cuddSwappingOutOfMem:
15013  while (moves != NULL) {
15014  move = moves->next;
15015  cuddDeallocMove(table, moves);
15016  moves = move;
15017  }
15018 
15019  return(0);
15020 
15021 } /* end of cuddSwapping */
unsigned int keys
Definition: cuddInt.h:314
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
int siftMaxSwap
Definition: cuddInt.h:396
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
static int ddSiftingBackward(DdManager *table, int size, Move *moves)
Definition: cuddInt.c:16108
DdSubtable * subtables
Definition: cuddInt.h:349
static Move * ddSwapAny(DdManager *table, int x, int y)
Definition: cuddInt.c:15668
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
static int result
Definition: cuddInt.c:7466
struct Move * next
Definition: cuddInt.h:474
int isolated
Definition: cuddInt.h:368
int ddTotalNumberSwapping
Definition: cuddInt.c:14489
long Cudd_Random(void)
Definition: cuddInt.c:22881

◆ cuddSymmCheck()

int cuddSymmCheck ( DdManager table,
int  x,
int  y 
)

AutomaticEnd Function********************************************************************

Synopsis [Checks for symmetry of x and y.]

Description [Checks for symmetry of x and y. Ignores projection functions, unless they are isolated. Returns 1 in case of symmetry; 0 otherwise.]

SideEffects [None]

Definition at line 17912 of file cuddInt.c.

17916  {
17917  DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10;
17918  int comple; /* f0 is complemented */
17919  int xsymmy; /* x and y may be positively symmetric */
17920  int xsymmyp; /* x and y may be negatively symmetric */
17921  int arccount; /* number of arcs from layer x to layer y */
17922  int TotalRefCount; /* total reference count of layer y minus 1 */
17923  int yindex;
17924  int i;
17925  DdNodePtr *list;
17926  int slots;
17927  DdNode *sentinel = &(table->sentinel);
17928 #ifdef DD_DEBUG
17929  int xindex;
17930 #endif
17931 
17932  /* Checks that x and y are not the projection functions.
17933  ** For x it is sufficient to check whether there is only one
17934  ** node; indeed, if there is one node, it is the projection function
17935  ** and it cannot point to y. Hence, if y isn't just the projection
17936  ** function, it has one arc coming from a layer different from x.
17937  */
17938  if (table->subtables[x].keys == 1) {
17939  return(0);
17940  }
17941  yindex = table->invperm[y];
17942  if (table->subtables[y].keys == 1) {
17943  if (table->vars[yindex]->ref == 1)
17944  return(0);
17945  }
17946 
17947  xsymmy = xsymmyp = 1;
17948  arccount = 0;
17949  slots = table->subtables[x].slots;
17950  list = table->subtables[x].nodelist;
17951  for (i = 0; i < slots; i++) {
17952  f = list[i];
17953  while (f != sentinel) {
17954  /* Find f1, f0, f11, f10, f01, f00. */
17955  f1 = cuddT(f);
17956  f0 = Cudd_Regular(cuddE(f));
17957  comple = Cudd_IsComplement(cuddE(f));
17958  if ((int) f1->index == yindex) {
17959  arccount++;
17960  f11 = cuddT(f1); f10 = cuddE(f1);
17961  } else {
17962  if ((int) f0->index != yindex) {
17963  /* If f is an isolated projection function it is
17964  ** allowed to bypass layer y.
17965  */
17966  if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1)
17967  return(0); /* f bypasses layer y */
17968  }
17969  f11 = f10 = f1;
17970  }
17971  if ((int) f0->index == yindex) {
17972  arccount++;
17973  f01 = cuddT(f0); f00 = cuddE(f0);
17974  } else {
17975  f01 = f00 = f0;
17976  }
17977  if (comple) {
17978  f01 = Cudd_Not(f01);
17979  f00 = Cudd_Not(f00);
17980  }
17981 
17982  if (f1 != DD_ONE(table) || f0 != DD_ONE(table) || f->ref != 1) {
17983  xsymmy &= f01 == f10;
17984  xsymmyp &= f11 == f00;
17985  if ((xsymmy == 0) && (xsymmyp == 0))
17986  return(0);
17987  }
17988 
17989  f = f->next;
17990  } /* while */
17991  } /* for */
17992 
17993  /* Calculate the total reference counts of y */
17994  TotalRefCount = -1; /* -1 for projection function */
17995  slots = table->subtables[y].slots;
17996  list = table->subtables[y].nodelist;
17997  for (i = 0; i < slots; i++) {
17998  f = list[i];
17999  while (f != sentinel) {
18000  TotalRefCount += f->ref;
18001  f = f->next;
18002  }
18003  }
18004 
18005 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
18006  if (arccount == TotalRefCount) {
18007  xindex = table->invperm[x];
18008  (void) fprintf(table->out,
18009  "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n",
18010  xindex,yindex,x,y);
18011  }
18012 #endif
18013 
18014  return(arccount == TotalRefCount);
18015 
18016  } /* end of cuddSymmCheck */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_Regular(node)
Definition: cudd.h:373
DdSubtable * subtables
Definition: cuddInt.h:349
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode sentinel
Definition: cuddInt.h:328
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:267
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
int * invperm
Definition: cuddInt.h:371
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ cuddSymmSifting()

int cuddSymmSifting ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [Symmetric sifting algorithm.]

Description [Symmetric sifting algorithm. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique subtable.
  2. Sift the variable up and down, remembering each time the total size of the DD heap and grouping variables that are symmetric.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 plus the number of symmetric variables if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddSymmSiftingConv]

Definition at line 18042 of file cuddInt.c.

18046  {
18047  int i;
18048  int *var;
18049  int size;
18050  int x;
18051  int result;
18052  int symvars;
18053  int symgroups;
18054 #ifdef DD_STATS
18055  int previousSize;
18056 #endif
18057 
18058  size = table->size;
18059 
18060  /* Find order in which to sift variables. */
18061  var = NULL;
18062  entry = ALLOC(int,size);
18063  if (entry == NULL) {
18064  table->errorCode = CUDD_MEMORY_OUT;
18065  goto ddSymmSiftingOutOfMem;
18066  }
18067  var = ALLOC(int,size);
18068  if (var == NULL) {
18069  table->errorCode = CUDD_MEMORY_OUT;
18070  goto ddSymmSiftingOutOfMem;
18071  }
18072 
18073  for (i = 0; i < size; i++) {
18074  x = table->perm[i];
18075  entry[i] = table->subtables[x].keys;
18076  var[i] = i;
18077  }
18078 
18079  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare);
18080 
18081  /* Initialize the symmetry of each subtable to itself. */
18082  for (i = lower; i <= upper; i++) {
18083  table->subtables[i].next = i;
18084  }
18085 
18086  for (i = 0; i < ddMin(table->siftMaxVar,size); i++) {
18087  if (ddTotalNumberSwapping >= table->siftMaxSwap)
18088  break;
18089  if (util_cpu_time() - table->startTime > table->timeLimit) {
18090  table->autoDyn = 0; /* prevent further reordering */
18091  break;
18092  }
18093  x = table->perm[var[i]];
18094 #ifdef DD_STATS
18095  previousSize = table->keys - table->isolated;
18096 #endif
18097  if (x < lower || x > upper) continue;
18098  if (table->subtables[x].next == (unsigned) x) {
18099  result = ddSymmSiftingAux(table,x,lower,upper);
18100  if (!result) goto ddSymmSiftingOutOfMem;
18101 #ifdef DD_STATS
18102  if (table->keys < (unsigned) previousSize + table->isolated) {
18103  (void) fprintf(table->out,"-");
18104  } else if (table->keys > (unsigned) previousSize +
18105  table->isolated) {
18106  (void) fprintf(table->out,"+"); /* should never happen */
18107  } else {
18108  (void) fprintf(table->out,"=");
18109  }
18110  fflush(table->out);
18111 #endif
18112  }
18113  }
18114 
18115  FREE(var);
18116  FREE(entry);
18117 
18118  ddSymmSummary(table, lower, upper, &symvars, &symgroups);
18119 
18120 #ifdef DD_STATS
18121  (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n",
18122  symvars);
18123  (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups",
18124  symgroups);
18125 #endif
18126 
18127  return(1+symvars);
18128 
18129  ddSymmSiftingOutOfMem:
18130 
18131  if (entry != NULL) FREE(entry);
18132  if (var != NULL) FREE(var);
18133 
18134  return(0);
18135 
18136  } /* end of cuddSymmSifting */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:302
unsigned long startTime
Definition: cuddInt.h:426
int size
Definition: cuddInt.h:345
static int ddSymmSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddInt.c:18365
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: util.c:34
int siftMaxVar
Definition: cuddInt.h:395
static int result
Definition: cuddInt.c:7466
static int ddSymmUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddInt.c:18337
unsigned int next
Definition: cuddInt.h:317
static int * entry
Definition: cuddInt.c:8422
int isolated
Definition: cuddInt.h:368
int ddTotalNumberSwapping
Definition: cuddInt.c:14489
int autoDyn
Definition: cuddInt.h:400
static void ddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
Definition: cuddInt.c:19400
int * perm
Definition: cuddInt.h:369
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddSymmSiftingConv()

int cuddSymmSiftingConv ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [Symmetric sifting to convergence algorithm.]

Description [Symmetric sifting to convergence algorithm. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique subtable.
  2. Sift the variable up and down, remembering each time the total size of the DD heap and grouping variables that are symmetric.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.
  5. Repeat 1-4 until no further improvement.

Returns 1 plus the number of symmetric variables if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddSymmSifting]

Definition at line 18163 of file cuddInt.c.

18167  {
18168  int i;
18169  int *var;
18170  int size;
18171  int x;
18172  int result;
18173  int symvars;
18174  int symgroups;
18175  int classes;
18176  int initialSize;
18177 #ifdef DD_STATS
18178  int previousSize;
18179 #endif
18180 
18181  initialSize = table->keys - table->isolated;
18182 
18183  size = table->size;
18184 
18185  /* Find order in which to sift variables. */
18186  var = NULL;
18187  entry = ALLOC(int,size);
18188  if (entry == NULL) {
18189  table->errorCode = CUDD_MEMORY_OUT;
18190  goto ddSymmSiftingConvOutOfMem;
18191  }
18192  var = ALLOC(int,size);
18193  if (var == NULL) {
18194  table->errorCode = CUDD_MEMORY_OUT;
18195  goto ddSymmSiftingConvOutOfMem;
18196  }
18197 
18198  for (i = 0; i < size; i++) {
18199  x = table->perm[i];
18200  entry[i] = table->subtables[x].keys;
18201  var[i] = i;
18202  }
18203 
18204  qsort((void *)var,size,sizeof(int),(DD_QSFP)ddSymmUniqueCompare);
18205 
18206  /* Initialize the symmetry of each subtable to itself
18207  ** for first pass of converging symmetric sifting.
18208  */
18209  for (i = lower; i <= upper; i++) {
18210  table->subtables[i].next = i;
18211  }
18212 
18213  for (i = 0; i < ddMin(table->siftMaxVar, table->size); i++) {
18214  if (ddTotalNumberSwapping >= table->siftMaxSwap)
18215  break;
18216  if (util_cpu_time() - table->startTime > table->timeLimit) {
18217  table->autoDyn = 0; /* prevent further reordering */
18218  break;
18219  }
18220  x = table->perm[var[i]];
18221  if (x < lower || x > upper) continue;
18222  /* Only sift if not in symmetry group already. */
18223  if (table->subtables[x].next == (unsigned) x) {
18224 #ifdef DD_STATS
18225  previousSize = table->keys - table->isolated;
18226 #endif
18227  result = ddSymmSiftingAux(table,x,lower,upper);
18228  if (!result) goto ddSymmSiftingConvOutOfMem;
18229 #ifdef DD_STATS
18230 if (table->keys < (unsigned) previousSize + table->isolated) {
18231 (void) fprintf(table->out,"-");
18232 } else if (table->keys > (unsigned) previousSize +
18233 table->isolated) {
18234 (void) fprintf(table->out,"+");
18235 } else {
18236 (void) fprintf(table->out,"=");
18237 }
18238 fflush(table->out);
18239 #endif
18240 }
18241 }
18242 
18243 /* Sifting now until convergence. */
18244 while ((unsigned) initialSize > table->keys - table->isolated) {
18245 initialSize = table->keys - table->isolated;
18246 #ifdef DD_STATS
18247 (void) fprintf(table->out,"\n");
18248 #endif
18249 /* Here we consider only one representative for each symmetry class. */
18250 for (x = lower, classes = 0; x <= upper; x++, classes++) {
18251 while ((unsigned) x < table->subtables[x].next) {
18252 x = table->subtables[x].next;
18253 }
18254 /* Here x is the largest index in a group.
18255 ** Groups consist of adjacent variables.
18256 ** Hence, the next increment of x will move it to a new group.
18257 */
18258 i = table->invperm[x];
18259 entry[i] = table->subtables[x].keys;
18260 var[classes] = i;
18261 }
18262 
18263 qsort((void *)var,classes,sizeof(int),(DD_QSFP)ddSymmUniqueCompare);
18264 
18265 /* Now sift. */
18266 for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) {
18267 if (ddTotalNumberSwapping >= table->siftMaxSwap)
18268 break;
18269 if (util_cpu_time() - table->startTime > table->timeLimit) {
18270 table->autoDyn = 0; /* prevent further reordering */
18271 break;
18272 }
18273 x = table->perm[var[i]];
18274 if ((unsigned) x >= table->subtables[x].next) {
18275 #ifdef DD_STATS
18276 previousSize = table->keys - table->isolated;
18277 #endif
18278 result = ddSymmSiftingConvAux(table,x,lower,upper);
18279 if (!result ) goto ddSymmSiftingConvOutOfMem;
18280 #ifdef DD_STATS
18281 if (table->keys < (unsigned) previousSize + table->isolated) {
18282 (void) fprintf(table->out,"-");
18283 } else if (table->keys > (unsigned) previousSize +
18284 table->isolated) {
18285 (void) fprintf(table->out,"+");
18286 } else {
18287 (void) fprintf(table->out,"=");
18288 }
18289 fflush(table->out);
18290 #endif
18291 }
18292 } /* for */
18293 }
18294 
18295 ddSymmSummary(table, lower, upper, &symvars, &symgroups);
18296 
18297 #ifdef DD_STATS
18298 (void) fprintf(table->out, "\n#:S_SIFTING %8d: symmetric variables\n",
18299 symvars);
18300 (void) fprintf(table->out, "#:G_SIFTING %8d: symmetric groups",
18301 symgroups);
18302 #endif
18303 
18304 FREE(var);
18305 FREE(entry);
18306 
18307 return(1+symvars);
18308 
18309 ddSymmSiftingConvOutOfMem:
18310 
18311 if (entry != NULL) FREE(entry);
18312 if (var != NULL) FREE(var);
18313 
18314 return(0);
18315 
18316 } /* end of cuddSymmSiftingConv */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:302
unsigned long startTime
Definition: cuddInt.h:426
int size
Definition: cuddInt.h:345
static int ddSymmSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddInt.c:18365
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: util.c:34
int siftMaxVar
Definition: cuddInt.h:395
static int result
Definition: cuddInt.c:7466
static int ddSymmUniqueCompare(int *ptrX, int *ptrY)
Definition: cuddInt.c:18337
unsigned int next
Definition: cuddInt.h:317
static int ddSymmSiftingConvAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddInt.c:18667
static int * entry
Definition: cuddInt.c:8422
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int ddTotalNumberSwapping
Definition: cuddInt.c:14489
int autoDyn
Definition: cuddInt.h:400
static void ddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
Definition: cuddInt.c:19400
int * perm
Definition: cuddInt.h:369
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddTestInteract()

int cuddTestInteract ( DdManager table,
int  x,
int  y 
)

Function********************************************************************

Synopsis [Test interaction matrix entries.]

Description [Given a pair of variables 0 <= x < y < table->size, tests whether the corresponding bit of the interaction matrix is 1. Returns the value of the bit.]

SideEffects [None]

SeeAlso []

Definition at line 10917 of file cuddInt.c.

10921 {
10922  int posn, word, bit, result;
10923 
10924  if (x > y) {
10925  int tmp = x;
10926  x = y;
10927  y = tmp;
10928  }
10929 #ifdef DD_DEBUG
10930  assert(x < y);
10931  assert(y < table->size);
10932  assert(x >= 0);
10933 #endif
10934 
10935  posn = ((((table->size << 1) - x - 3) * x) >> 1) + y - 1;
10936  word = posn >> LOGBPL;
10937  bit = posn & (BPL-1);
10938  result = (table->interact[word] >> bit) & 1L;
10939  return(result);
10940 
10941 } /* end of cuddTestInteract */
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
#define BPL
Definition: cuddInt.c:12624
long * interact
Definition: cuddInt.h:377
#define LOGBPL
Definition: cuddInt.c:12625
static int result
Definition: cuddInt.c:7466

◆ cuddTreeSifting()

int cuddTreeSifting ( DdManager table,
Cudd_ReorderingType  method 
)

AutomaticEnd Function********************************************************************

Synopsis [Tree sifting algorithm.]

Description [Tree sifting algorithm. Assumes that a tree representing a group hierarchy is passed as a parameter. It then reorders each group in postorder fashion by calling ddTreeSiftingAux. Assumes that no dead nodes are present. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 8507 of file cuddInt.c.

8510 {
8511  int i;
8512  int nvars;
8513  int result;
8514  int tempTree;
8515 
8516  /* If no tree is provided we create a temporary one in which all
8517  ** variables are in a single group. After reordering this tree is
8518  ** destroyed.
8519  */
8520  tempTree = table->tree == NULL;
8521  if (tempTree) {
8522  table->tree = Mtr_InitGroupTree(0,table->size);
8523  table->tree->index = table->invperm[0];
8524  }
8525  nvars = table->size;
8526 
8527 #ifdef DD_DEBUG
8528  if (pr > 0 && !tempTree) (void) fprintf(table->out,"cuddTreeSifting:");
8529  Mtr_PrintGroups(table->tree,pr <= 0);
8530 #endif
8531 
8532 #ifdef DD_STATS
8533  extsymmcalls = 0;
8534  extsymm = 0;
8535  secdiffcalls = 0;
8536  secdiff = 0;
8537  secdiffmisfire = 0;
8538 
8539  (void) fprintf(table->out,"\n");
8540  if (!tempTree)
8541  (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n",
8542  ddCountInternalMtrNodes(table,table->tree));
8543 #endif
8544 
8545  /* Initialize the group of each subtable to itself. Initially
8546  ** there are no groups. Groups are created according to the tree
8547  ** structure in postorder fashion.
8548  */
8549  for (i = 0; i < nvars; i++)
8550  table->subtables[i].next = i;
8551 
8552 
8553  /* Reorder. */
8554  result = ddTreeSiftingAux(table, table->tree, method);
8555 
8556 #ifdef DD_STATS /* print stats */
8557  if (!tempTree && method == CUDD_REORDER_GROUP_SIFT &&
8558  (table->groupcheck == CUDD_GROUP_CHECK7 ||
8559  table->groupcheck == CUDD_GROUP_CHECK5)) {
8560  (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls);
8561  (void) fprintf(table->out,"extsymm = %d",extsymm);
8562  }
8563  if (!tempTree && method == CUDD_REORDER_GROUP_SIFT &&
8564  table->groupcheck == CUDD_GROUP_CHECK7) {
8565  (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls);
8566  (void) fprintf(table->out,"secdiff = %d\n",secdiff);
8567  (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire);
8568  }
8569 #endif
8570 
8571  if (tempTree)
8572  Cudd_FreeTree(table);
8573  else
8574  Mtr_ReorderGroups(table->tree, table->perm);
8575 
8576  return(result);
8577 
8578 } /* end of cuddTreeSifting */
Cudd_AggregationType groupcheck
Definition: cuddInt.h:410
int size
Definition: cuddInt.h:345
static int ddTreeSiftingAux(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddInt.c:8597
DdSubtable * subtables
Definition: cuddInt.h:349
void Mtr_ReorderGroups(MtrNode *treenode, int *permutation)
Definition: mtr.c:702
MtrNode * tree
Definition: cuddInt.h:408
MtrHalfWord index
Definition: mtr.h:130
FILE * out
Definition: cuddInt.h:423
void Mtr_PrintGroups(MtrNode *root, int silent)
Definition: mtr.c:773
MtrNode * Mtr_InitGroupTree(int lower, int size)
Definition: mtr.c:410
static int result
Definition: cuddInt.c:7466
void Cudd_FreeTree(DdManager *dd)
Definition: cuddInt.c:1807
unsigned int next
Definition: cuddInt.h:317
int * invperm
Definition: cuddInt.h:371
int * perm
Definition: cuddInt.h:369

◆ cuddUniqueConst()

DdNode* cuddUniqueConst ( DdManager unique,
CUDD_VALUE_TYPE  value 
)

Function********************************************************************

Synopsis [Checks the unique table for the existence of a constant node.]

Description [Checks the unique table for the existence of a constant node. If it does not exist, it creates a new one. Does not modify the reference count of whatever is returned. A newly created internal node comes back with a reference count 0. Returns a pointer to the new node.]

SideEffects [None]

Definition at line 20837 of file cuddInt.c.

20840 {
20841 int pos;
20842 DdNodePtr *nodelist;
20843 DdNode *looking;
20844 hack split;
20845 
20846 #ifdef DD_UNIQUE_PROFILE
20847 unique->uniqueLookUps++;
20848 #endif
20849 
20850 if (unique->constants.keys > unique->constants.maxKeys) {
20851 if (unique->gcEnabled && ((unique->dead > unique->minDead) ||
20852 (10 * unique->constants.dead > 9 * unique->constants.keys))) { /* too many dead */
20853 (void) cuddGarbageCollect(unique,1);
20854 } else {
20856 }
20857 }
20858 
20859 cuddAdjust(value); /* for the case of crippled infinities */
20860 
20861 if (ddAbs(value) < unique->epsilon) {
20862 value = 0.0;
20863 }
20864 split.value = value;
20865 
20866 pos = ddHash(split.bits[0], split.bits[1], unique->constants.shift);
20867 nodelist = unique->constants.nodelist;
20868 looking = nodelist[pos];
20869 
20870 /* Here we compare values both for equality and for difference less
20871  * than epsilon. The first comparison is required when values are
20872  * infinite, since Infinity - Infinity is NaN and NaN < X is 0 for
20873  * every X.
20874  */
20875 while (looking != NULL) {
20876 if (looking->type.value == value ||
20877 ddEqualVal(looking->type.value,value,unique->epsilon)) {
20878 if (looking->ref == 0) {
20879 cuddReclaim(unique,looking);
20880 }
20881 return(looking);
20882 }
20883 looking = looking->next;
20884 #ifdef DD_UNIQUE_PROFILE
20885 unique->uniqueLinks++;
20886 #endif
20887 }
20888 
20889 unique->keys++;
20890 unique->constants.keys++;
20891 
20892 looking = cuddAllocNode(unique);
20893 if (looking == NULL) return(NULL);
20894 looking->index = CUDD_CONST_INDEX;
20895 looking->type.value = value;
20896 looking->next = nodelist[pos];
20897 nodelist[pos] = looking;
20898 
20899 return(looking);
20900 
20901 } /* end of cuddUniqueConst */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
DdNode * cuddAllocNode(DdManager *unique)
Definition: cuddInt.c:19624
#define ddHash(f, g, s)
Definition: cuddInt.h:696
union DdNode::@0 type
Definition: cudd.h:264
unsigned int bits[2]
Definition: cuddInt.c:19539
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddInt.c:20120
unsigned int dead
Definition: cuddInt.h:355
CUDD_VALUE_TYPE value
Definition: cudd.h:269
unsigned int keys
Definition: cuddInt.h:353
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:267
#define ddAbs(x)
Definition: cuddInt.h:799
unsigned int maxKeys
Definition: cuddInt.h:315
int gcEnabled
Definition: cuddInt.h:360
#define CUDD_CONST_INDEX
Definition: cudd.h:107
DdNode ** nodelist
Definition: cuddInt.h:311
CUDD_VALUE_TYPE value
Definition: cuddInt.c:19538
#define ddEqualVal(x, y, e)
Definition: cuddInt.h:814
void cuddRehash(DdManager *unique, int i)
Definition: cuddInt.c:20917
DdHalfWord index
Definition: cudd.h:265
CUDD_VALUE_TYPE epsilon
Definition: cuddInt.h:390
DdSubtable constants
Definition: cuddInt.h:351
#define cuddAdjust(x)
Definition: cuddInt.h:932
int shift
Definition: cuddInt.h:312
unsigned int minDead
Definition: cuddInt.h:358
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddInt.c:14223

◆ cuddUniqueInter()

DdNode* cuddUniqueInter ( DdManager unique,
int  index,
DdNode T,
DdNode E 
)

Function********************************************************************

Synopsis [Checks the unique table for the existence of an internal node.]

Description [Checks the unique table for the existence of an internal node. If it does not exist, it creates a new one. Does not modify the reference count of whatever is returned. A newly created internal node comes back with a reference count 0. For a newly created node, increments the reference counts of what T and E point to. Returns a pointer to the new node if successful; NULL if memory is exhausted or if reordering took place.]

SideEffects [None]

SeeAlso [cuddUniqueInterZdd]

Definition at line 20495 of file cuddInt.c.

20500 {
20501 int pos;
20502 unsigned int level;
20503 int retval;
20504 DdNodePtr *nodelist;
20505 DdNode *looking;
20506 DdNodePtr *previousP;
20507 DdSubtable *subtable;
20508 int gcNumber;
20509 
20510 #ifdef DD_UNIQUE_PROFILE
20511 unique->uniqueLookUps++;
20512 #endif
20513 
20514 if ((0x1ffffUL & (unsigned long) unique->cacheMisses) == 0) {
20515 if (util_cpu_time() - unique->startTime > unique->timeLimit) {
20517 return(NULL);
20518 }
20519 }
20520 if (index >= unique->size) {
20521 int amount = ddMax(DD_DEFAULT_RESIZE,unique->size/20);
20522 if (!ddResizeTable(unique,index,amount)) return(NULL);
20523 }
20524 
20525 level = unique->perm[index];
20526 subtable = &(unique->subtables[level]);
20527 
20528 #ifdef DD_DEBUG
20529 assert(level < (unsigned) cuddI(unique,T->index));
20530 assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index));
20531 #endif
20532 
20533 pos = ddHash(T, E, subtable->shift);
20534 nodelist = subtable->nodelist;
20535 previousP = &(nodelist[pos]);
20536 looking = *previousP;
20537 
20538 while (T < cuddT(looking)) {
20539 previousP = &(looking->next);
20540 looking = *previousP;
20541 #ifdef DD_UNIQUE_PROFILE
20542 unique->uniqueLinks++;
20543 #endif
20544 }
20545 while (T == cuddT(looking) && E < cuddE(looking)) {
20546 previousP = &(looking->next);
20547 looking = *previousP;
20548 #ifdef DD_UNIQUE_PROFILE
20549 unique->uniqueLinks++;
20550 #endif
20551 }
20552 if (T == cuddT(looking) && E == cuddE(looking)) {
20553 if (looking->ref == 0) {
20554 cuddReclaim(unique,looking);
20555 }
20556 return(looking);
20557 }
20558 
20559 /* countDead is 0 if deads should be counted and ~0 if they should not. */
20560 if (unique->autoDyn &&
20561 unique->keys - (unique->dead & unique->countDead) >= unique->nextDyn &&
20562 unique->maxReorderings > 0) {
20563 unsigned long cpuTime;
20564 #ifdef DD_DEBUG
20565 retval = Cudd_DebugCheck(unique);
20566 if (retval != 0) return(NULL);
20567 retval = Cudd_CheckKeys(unique);
20568 if (retval != 0) return(NULL);
20569 #endif
20570 retval = Cudd_ReduceHeap(unique,unique->autoMethod,10); /* 10 = whatever */
20571 unique->maxReorderings--;
20572 if (retval == 0) {
20573 unique->reordered = 2;
20574 } else if ((cpuTime = util_cpu_time()) - unique->startTime > unique->timeLimit) {
20576 unique->reordered = 0;
20577 } else if (unique->timeLimit - (cpuTime - unique->startTime)
20578 < unique->reordTime) {
20579 unique->autoDyn = 0;
20580 }
20581 #ifdef DD_DEBUG
20582 retval = Cudd_DebugCheck(unique);
20583 if (retval != 0) unique->reordered = 2;
20584 retval = Cudd_CheckKeys(unique);
20585 if (retval != 0) unique->reordered = 2;
20586 #endif
20587 return(NULL);
20588 }
20589 
20590 if (subtable->keys > subtable->maxKeys) {
20591 if (unique->gcEnabled &&
20592 ((unique->dead > unique->minDead) ||
20593 ((unique->dead > unique->minDead / 2) &&
20594 (subtable->dead > subtable->keys * 0.95)))) { /* too many dead */
20595 if (util_cpu_time() - unique->startTime > unique->timeLimit) {
20597 return(NULL);
20598 }
20599 (void) cuddGarbageCollect(unique,1);
20600 } else {
20601 cuddRehash(unique,(int)level);
20602 }
20603 /* Update pointer to insertion point. In the case of rehashing,
20604 ** the slot may have changed. In the case of garbage collection,
20605 ** the predecessor may have been dead. */
20606 pos = ddHash(T, E, subtable->shift);
20607 nodelist = subtable->nodelist;
20608 previousP = &(nodelist[pos]);
20609 looking = *previousP;
20610 
20611 while (T < cuddT(looking)) {
20612 previousP = &(looking->next);
20613 looking = *previousP;
20614 #ifdef DD_UNIQUE_PROFILE
20615 unique->uniqueLinks++;
20616 #endif
20617 }
20618 while (T == cuddT(looking) && E < cuddE(looking)) {
20619 previousP = &(looking->next);
20620 looking = *previousP;
20621 #ifdef DD_UNIQUE_PROFILE
20622 unique->uniqueLinks++;
20623 #endif
20624 }
20625 }
20626 
20627 gcNumber = unique->garbageCollections;
20628 looking = cuddAllocNode(unique);
20629 if (looking == NULL) {
20630 return(NULL);
20631 }
20632 unique->keys++;
20633 subtable->keys++;
20634 
20635 if (gcNumber != unique->garbageCollections) {
20636 DdNode *looking2;
20637 pos = ddHash(T, E, subtable->shift);
20638 nodelist = subtable->nodelist;
20639 previousP = &(nodelist[pos]);
20640 looking2 = *previousP;
20641 
20642 while (T < cuddT(looking2)) {
20643 previousP = &(looking2->next);
20644 looking2 = *previousP;
20645 #ifdef DD_UNIQUE_PROFILE
20646 unique->uniqueLinks++;
20647 #endif
20648 }
20649 while (T == cuddT(looking2) && E < cuddE(looking2)) {
20650 previousP = &(looking2->next);
20651 looking2 = *previousP;
20652 #ifdef DD_UNIQUE_PROFILE
20653 unique->uniqueLinks++;
20654 #endif
20655 }
20656 }
20657 looking->index = index;
20658 cuddT(looking) = T;
20659 cuddE(looking) = E;
20660 looking->next = *previousP;
20661 *previousP = looking;
20662 cuddSatInc(T->ref); /* we know T is a regular pointer */
20663 cuddRef(E);
20664 
20665 #ifdef DD_DEBUG
20666 cuddCheckCollisionOrdering(unique,level,pos);
20667 #endif
20668 
20669 return(looking);
20670 
20671 } /* end of cuddUniqueInter */
DdHalfWord ref
Definition: cudd.h:266
#define cuddRef(n)
Definition: cuddInt.h:557
unsigned int keys
Definition: cuddInt.h:314
DdNode * cuddAllocNode(DdManager *unique)
Definition: cuddInt.c:19624
#define ddHash(f, g, s)
Definition: cuddInt.h:696
unsigned long reordTime
Definition: cuddInt.h:434
Cudd_ReorderingType autoMethod
Definition: cuddInt.h:402
Definition: cudd.h:264
unsigned long startTime
Definition: cuddInt.h:426
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
#define Cudd_Regular(node)
Definition: cudd.h:373
int Cudd_ReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
Definition: cuddInt.c:14558
int garbageCollections
Definition: cuddInt.h:432
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddInt.c:20120
unsigned int countDead
Definition: cuddInt.h:407
int reordered
Definition: cuddInt.h:392
unsigned int nextDyn
Definition: cuddInt.h:406
unsigned int dead
Definition: cuddInt.h:355
unsigned int keys
Definition: cuddInt.h:353
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:267
static int ddResizeTable(DdManager *unique, int index, int amount)
Definition: cuddInt.c:21378
unsigned int maxKeys
Definition: cuddInt.h:315
int gcEnabled
Definition: cuddInt.h:360
#define ddMax(x, y)
Definition: cuddInt.h:785
DdNode ** nodelist
Definition: cuddInt.h:311
long util_cpu_time(void)
Definition: util.c:34
#define cuddT(node)
Definition: cuddInt.h:609
int Cudd_CheckKeys(DdManager *table)
Definition: cuddInt.c:5577
unsigned int maxReorderings
Definition: cuddInt.h:394
void cuddRehash(DdManager *unique, int i)
Definition: cuddInt.c:20917
#define cuddI(dd, index)
Definition: cuddInt.h:659
#define DD_DEFAULT_RESIZE
Definition: cuddInt.h:103
DdHalfWord index
Definition: cudd.h:265
double cacheMisses
Definition: cuddInt.h:339
#define cuddE(node)
Definition: cuddInt.h:625
int Cudd_DebugCheck(DdManager *table)
Definition: cuddInt.c:5255
int autoDyn
Definition: cuddInt.h:400
int shift
Definition: cuddInt.h:312
int * perm
Definition: cuddInt.h:369
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
unsigned int minDead
Definition: cuddInt.h:358
#define cuddSatInc(x)
Definition: cuddInt.h:831
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddInt.c:14223

◆ cuddUniqueInterIVO()

DdNode* cuddUniqueInterIVO ( DdManager unique,
int  index,
DdNode T,
DdNode E 
)

Function********************************************************************

Synopsis [Wrapper for cuddUniqueInter that is independent of variable ordering.]

Description [Wrapper for cuddUniqueInter that is independent of variable ordering (IVO). This function does not require parameter index to precede the indices of the top nodes of T and E in the variable order. Returns a pointer to the result node under normal conditions; NULL if reordering occurred or memory was exhausted.]

SideEffects [None]

SeeAlso [cuddUniqueInter Cudd_MakeBddFromZddCover]

Definition at line 20691 of file cuddInt.c.

20696 {
20697 DdNode *result;
20698 DdNode *v;
20699 
20700 v = cuddUniqueInter(unique, index, DD_ONE(unique),
20701 Cudd_Not(DD_ONE(unique)));
20702 if (v == NULL)
20703 return(NULL);
20704 /* Since v is a projection function, we can skip the call to cuddRef. */
20705 result = cuddBddIteRecur(unique, v, T, E);
20706 return(result);
20707 
20708 } /* end of cuddUniqueInterIVO */
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
DdNode * cuddBddIteRecur(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:3380
static int result
Definition: cuddInt.c:7466
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ cuddUniqueInterZdd()

DdNode* cuddUniqueInterZdd ( DdManager unique,
int  index,
DdNode T,
DdNode E 
)

Function********************************************************************

Synopsis [Checks the unique table for the existence of an internal ZDD node.]

Description [Checks the unique table for the existence of an internal ZDD node. If it does not exist, it creates a new one. Does not modify the reference count of whatever is returned. A newly created internal node comes back with a reference count 0. For a newly created node, increments the reference counts of what T and E point to. Returns a pointer to the new node if successful; NULL if memory is exhausted or if reordering took place.]

SideEffects [None]

SeeAlso [cuddUniqueInter]

Definition at line 20730 of file cuddInt.c.

20735 {
20736 int pos;
20737 unsigned int level;
20738 int retval;
20739 DdNodePtr *nodelist;
20740 DdNode *looking;
20741 DdSubtable *subtable;
20742 
20743 #ifdef DD_UNIQUE_PROFILE
20744 unique->uniqueLookUps++;
20745 #endif
20746 
20747 if (index >= unique->sizeZ) {
20748 if (!cuddResizeTableZdd(unique,index)) return(NULL);
20749 }
20750 
20751 level = unique->permZ[index];
20752 subtable = &(unique->subtableZ[level]);
20753 
20754 #ifdef DD_DEBUG
20755 assert(level < (unsigned) cuddIZ(unique,T->index));
20756 assert(level < (unsigned) cuddIZ(unique,Cudd_Regular(E)->index));
20757 #endif
20758 
20759 if (subtable->keys > subtable->maxKeys) {
20760 if (unique->gcEnabled && ((unique->deadZ > unique->minDead) ||
20761 (10 * subtable->dead > 9 * subtable->keys))) { /* too many dead */
20762 (void) cuddGarbageCollect(unique,1);
20763 } else {
20764 ddRehashZdd(unique,(int)level);
20765 }
20766 }
20767 
20768 pos = ddHash(T, E, subtable->shift);
20769 nodelist = subtable->nodelist;
20770 looking = nodelist[pos];
20771 
20772 while (looking != NULL) {
20773 if (cuddT(looking) == T && cuddE(looking) == E) {
20774 if (looking->ref == 0) {
20775 cuddReclaimZdd(unique,looking);
20776 }
20777 return(looking);
20778 }
20779 looking = looking->next;
20780 #ifdef DD_UNIQUE_PROFILE
20781 unique->uniqueLinks++;
20782 #endif
20783 }
20784 
20785 /* countDead is 0 if deads should be counted and ~0 if they should not. */
20786 if (unique->autoDynZ &&
20787 unique->keysZ - (unique->deadZ & unique->countDead) >= unique->nextDyn) {
20788 #ifdef DD_DEBUG
20789 retval = Cudd_DebugCheck(unique);
20790 if (retval != 0) return(NULL);
20791 retval = Cudd_CheckKeys(unique);
20792 if (retval != 0) return(NULL);
20793 #endif
20794 retval = Cudd_zddReduceHeap(unique,unique->autoMethodZ,10); /* 10 = whatever */
20795 if (retval == 0) unique->reordered = 2;
20796 #ifdef DD_DEBUG
20797 retval = Cudd_DebugCheck(unique);
20798 if (retval != 0) unique->reordered = 2;
20799 retval = Cudd_CheckKeys(unique);
20800 if (retval != 0) unique->reordered = 2;
20801 #endif
20802 return(NULL);
20803 }
20804 
20805 unique->keysZ++;
20806 subtable->keys++;
20807 
20808 looking = cuddAllocNode(unique);
20809 if (looking == NULL) return(NULL);
20810 looking->index = index;
20811 cuddT(looking) = T;
20812 cuddE(looking) = E;
20813 looking->next = nodelist[pos];
20814 nodelist[pos] = looking;
20815 cuddRef(T);
20816 cuddRef(E);
20817 
20818 return(looking);
20819 
20820 } /* end of cuddUniqueInterZdd */
DdHalfWord ref
Definition: cudd.h:266
#define cuddRef(n)
Definition: cuddInt.h:557
unsigned int keys
Definition: cuddInt.h:314
DdNode * cuddAllocNode(DdManager *unique)
Definition: cuddInt.c:19624
#define ddHash(f, g, s)
Definition: cuddInt.h:696
#define cuddIZ(dd, index)
Definition: cuddInt.h:677
Definition: cudd.h:264
unsigned int deadZ
Definition: cuddInt.h:356
#define assert(ex)
Definition: util.h:141
#define Cudd_Regular(node)
Definition: cudd.h:373
Cudd_ReorderingType autoMethodZ
Definition: cuddInt.h:403
int * permZ
Definition: cuddInt.h:370
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddInt.c:20120
unsigned int countDead
Definition: cuddInt.h:407
int reordered
Definition: cuddInt.h:392
unsigned int nextDyn
Definition: cuddInt.h:406
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:267
unsigned int maxKeys
Definition: cuddInt.h:315
int gcEnabled
Definition: cuddInt.h:360
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
int Cudd_CheckKeys(DdManager *table)
Definition: cuddInt.c:5577
int Cudd_zddReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
Definition: cuddInt.c:29608
void cuddReclaimZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14277
int sizeZ
Definition: cuddInt.h:346
DdHalfWord index
Definition: cudd.h:265
int autoDynZ
Definition: cuddInt.h:401
#define cuddE(node)
Definition: cuddInt.h:625
int Cudd_DebugCheck(DdManager *table)
Definition: cuddInt.c:5255
int cuddResizeTableZdd(DdManager *unique, int index)
Definition: cuddInt.c:21093
int shift
Definition: cuddInt.h:312
unsigned int keysZ
Definition: cuddInt.h:354
static void ddRehashZdd(DdManager *unique, int i)
Definition: cuddInt.c:21274
unsigned int minDead
Definition: cuddInt.h:358
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddUniqueLookup()

static DdNode * cuddUniqueLookup ( DdManager unique,
int  index,
DdNode T,
DdNode E 
)
static

Function********************************************************************

Synopsis [Checks the unique table for the existence of an internal node.]

Description [Checks the unique table for the existence of an internal node. Returns a pointer to the node if it is in the table; NULL otherwise.]

SideEffects [None]

SeeAlso [cuddUniqueInter]

Definition at line 23428 of file cuddInt.c.

23433 {
23434 int posn;
23435 unsigned int level;
23436 DdNodePtr *nodelist;
23437 DdNode *looking;
23438 DdSubtable *subtable;
23439 
23440 if (index >= unique->size) {
23441 return(NULL);
23442 }
23443 
23444 level = unique->perm[index];
23445 subtable = &(unique->subtables[level]);
23446 
23447 #ifdef DD_DEBUG
23448 assert(level < (unsigned) cuddI(unique,T->index));
23449 assert(level < (unsigned) cuddI(unique,Cudd_Regular(E)->index));
23450 #endif
23451 
23452 posn = ddHash(T, E, subtable->shift);
23453 nodelist = subtable->nodelist;
23454 looking = nodelist[posn];
23455 
23456 while (T < cuddT(looking)) {
23457 looking = Cudd_Regular(looking->next);
23458 }
23459 while (T == cuddT(looking) && E < cuddE(looking)) {
23460 looking = Cudd_Regular(looking->next);
23461 }
23462 if (cuddT(looking) == T && cuddE(looking) == E) {
23463 return(looking);
23464 }
23465 
23466 return(NULL);
23467 
23468 } /* end of cuddUniqueLookup */
#define ddHash(f, g, s)
Definition: cuddInt.h:696
Definition: cudd.h:264
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
#define Cudd_Regular(node)
Definition: cudd.h:373
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode * next
Definition: cudd.h:267
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
int shift
Definition: cuddInt.h:312
int * perm
Definition: cuddInt.h:369

◆ cuddUpdateInteractionMatrix()

void cuddUpdateInteractionMatrix ( DdManager table,
int  xindex,
int  yindex 
)

Function********************************************************************

Synopsis [Updates the interaction matrix.]

Description []

SideEffects [none]

SeeAlso []

Definition at line 13228 of file cuddInt.c.

13232 {
13233  int i;
13234  for (i = 0; i < yindex; i++) {
13235  if (i != xindex && cuddTestInteract(table,i,yindex)) {
13236  if (i < xindex) {
13237  cuddSetInteract(table,i,xindex);
13238  } else {
13239  cuddSetInteract(table,xindex,i);
13240  }
13241  }
13242  }
13243  for (i = yindex+1; i < table->size; i++) {
13244  if (i != xindex && cuddTestInteract(table,yindex,i)) {
13245  if (i < xindex) {
13246  cuddSetInteract(table,i,xindex);
13247  } else {
13248  cuddSetInteract(table,xindex,i);
13249  }
13250  }
13251  }
13252 
13253 } /* end of cuddUpdateInteractionMatrix */
int size
Definition: cuddInt.h:345
void cuddSetInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10882
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917

◆ cuddWindowReorder()

int cuddWindowReorder ( DdManager table,
int  low,
int  high,
Cudd_ReorderingType  submethod 
)

AutomaticEnd Function********************************************************************

Synopsis [Reorders by applying the method of the sliding window.]

Description [Reorders by applying the method of the sliding window. Tries all possible permutations to the variables in a window that slides from low to high. The size of the window is determined by submethod. Assumes that no dead nodes are present. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 24123 of file cuddInt.c.

24128 {
24129 
24130 int res;
24131 #ifdef DD_DEBUG
24132 int supposedOpt;
24133 #endif
24134 
24135 switch (submethod) {
24137 res = ddWindow2(table,low,high);
24138 break;
24140 res = ddWindow3(table,low,high);
24141 break;
24143 res = ddWindow4(table,low,high);
24144 break;
24146 res = ddWindowConv2(table,low,high);
24147 break;
24149 res = ddWindowConv3(table,low,high);
24150 #ifdef DD_DEBUG
24151 supposedOpt = table->keys - table->isolated;
24152 res = ddWindow3(table,low,high);
24153 if (table->keys - table->isolated != (unsigned) supposedOpt) {
24154 (void) fprintf(table->err, "Convergence failed! (%d != %d)\n",
24155 table->keys - table->isolated, supposedOpt);
24156 }
24157 #endif
24158 break;
24160 res = ddWindowConv4(table,low,high);
24161 #ifdef DD_DEBUG
24162 supposedOpt = table->keys - table->isolated;
24163 res = ddWindow4(table,low,high);
24164 if (table->keys - table->isolated != (unsigned) supposedOpt) {
24165 (void) fprintf(table->err,"Convergence failed! (%d != %d)\n",
24166 table->keys - table->isolated, supposedOpt);
24167 }
24168 #endif
24169 break;
24170 default: return(0);
24171 }
24172 
24173 return(res);
24174 
24175 } /* end of cuddWindowReorder */
static int ddWindow2(DdManager *table, int low, int high)
Definition: cuddInt.c:24195
FILE * err
Definition: cuddInt.h:424
unsigned int keys
Definition: cuddInt.h:353
static int ddWindowConv3(DdManager *table, int low, int high)
Definition: cuddInt.c:24484
static int ddWindow4(DdManager *table, int low, int high)
Definition: cuddInt.c:24838
static int ddWindow3(DdManager *table, int low, int high)
Definition: cuddInt.c:24437
int isolated
Definition: cuddInt.h:368
static int ddWindowConv2(DdManager *table, int low, int high)
Definition: cuddInt.c:24249
static int ddWindowConv4(DdManager *table, int low, int high)
Definition: cuddInt.c:24885

◆ cuddXorLinear()

static void cuddXorLinear ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [XORs two rows of the linear transform matrix.]

Description [XORs two rows of the linear transform matrix and replaces the first row with the result.]

SideEffects [none]

SeeAlso []

Definition at line 13863 of file cuddInt.c.

13867 {
13868  int i;
13869  int nvars = table->size;
13870  int wordsPerRow = ((nvars - 1) >> LOGBPL) + 1;
13871  int xstart = wordsPerRow * x;
13872  int ystart = wordsPerRow * y;
13873  long *linear = table->linear;
13874 
13875  for (i = 0; i < wordsPerRow; i++) {
13876  linear[xstart+i] ^= linear[ystart+i];
13877  }
13878 
13879 } /* end of cuddXorLinear */
int size
Definition: cuddInt.h:345
long * linear
Definition: cuddInt.h:378
#define LOGBPL
Definition: cuddInt.c:12625

◆ cuddZddAlignToBdd()

int cuddZddAlignToBdd ( DdManager table)

Function********************************************************************

Synopsis [Reorders ZDD variables according to the order of the BDD variables.]

Description [Reorders ZDD variables according to the order of the BDD variables. This function can be called at the end of BDD reordering to insure that the order of the ZDD variables is consistent with the order of the BDD variables. The number of ZDD variables must be a multiple of the number of BDD variables. Let M be the ratio of the two numbers. cuddZddAlignToBdd then considers the ZDD variables from M*i to (M+1)*i-1 as corresponding to BDD variable i. This function should be normally called from Cudd_ReduceHeap, which clears the cache. Returns 1 in case of success; 0 otherwise.]

SideEffects [Changes the ZDD variable order for all diagrams and performs garbage collection of the ZDD unique table.]

SeeAlso [Cudd_zddShuffleHeap Cudd_ReduceHeap]

Definition at line 29753 of file cuddInt.c.

29755 {
29756  int *invpermZ; /* permutation array */
29757  int M; /* ratio of ZDD variables to BDD variables */
29758  int i,j; /* loop indices */
29759  int result; /* return value */
29760 
29761  /* We assume that a ratio of 0 is OK. */
29762  if (table->sizeZ == 0)
29763  return(1);
29764 
29765  empty = table->zero;
29766  M = table->sizeZ / table->size;
29767  /* Check whether the number of ZDD variables is a multiple of the
29768  ** number of BDD variables.
29769  */
29770  if (M * table->size != table->sizeZ)
29771  return(0);
29772  /* Create and initialize the inverse permutation array. */
29773  invpermZ = ALLOC(int,table->sizeZ);
29774  if (invpermZ == NULL) {
29775  table->errorCode = CUDD_MEMORY_OUT;
29776  return(0);
29777  }
29778  for (i = 0; i < table->size; i++) {
29779  int index = table->invperm[i];
29780  int indexZ = index * M;
29781  int levelZ = table->permZ[indexZ];
29782  levelZ = (levelZ / M) * M;
29783  for (j = 0; j < M; j++) {
29784  invpermZ[M * i + j] = table->invpermZ[levelZ + j];
29785  }
29786  }
29787  /* Eliminate dead nodes. Do not scan the cache again, because we
29788  ** assume that Cudd_ReduceHeap has already cleared it.
29789  */
29790  cuddGarbageCollect(table,0);
29791 
29792  result = zddShuffle(table, invpermZ);
29793  FREE(invpermZ);
29794  /* Fix the ZDD variable group tree. */
29795  zddFixTree(table,table->treeZ);
29796  return(result);
29797 
29798 } /* end of cuddZddAlignToBdd */
static void zddFixTree(DdManager *table, MtrNode *treenode)
Definition: cuddInt.c:31050
#define FREE(obj)
Definition: util.h:80
int * invpermZ
Definition: cuddInt.h:372
int size
Definition: cuddInt.h:345
DdNode * zero
Definition: cuddInt.h:330
static DdNode * empty
Definition: cuddInt.c:28567
int * permZ
Definition: cuddInt.h:370
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddInt.c:20120
#define ALLOC(type, num)
Definition: util.h:76
int sizeZ
Definition: cuddInt.h:346
static int result
Definition: cuddInt.c:7466
MtrNode * treeZ
Definition: cuddInt.h:409
static int zddShuffle(DdManager *table, int *permutation)
Definition: cuddInt.c:30939
int * invperm
Definition: cuddInt.h:371
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ cuddZddChangeAux()

DdNode* cuddZddChangeAux ( DdManager zdd,
DdNode P,
DdNode zvar 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddChange.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 31650 of file cuddInt.c.

31654 {
31655  int top_var, level;
31656  DdNode *res, *t, *e;
31657  DdNode *base = DD_ONE(zdd);
31658  DdNode *empty = DD_ZERO(zdd);
31659 
31660  statLine(zdd);
31661  if (P == empty)
31662  return(empty);
31663  if (P == base)
31664  return(zvar);
31665 
31666  /* Check cache. */
31667  res = cuddCacheLookup2Zdd(zdd, cuddZddChangeAux, P, zvar);
31668  if (res != NULL)
31669  return(res);
31670 
31671  top_var = zdd->permZ[P->index];
31672  level = zdd->permZ[zvar->index];
31673 
31674  if (top_var > level) {
31675  res = cuddZddGetNode(zdd, zvar->index, P, DD_ZERO(zdd));
31676  if (res == NULL) return(NULL);
31677  } else if (top_var == level) {
31678  res = cuddZddGetNode(zdd, zvar->index, cuddE(P), cuddT(P));
31679  if (res == NULL) return(NULL);
31680  } else {
31681  t = cuddZddChangeAux(zdd, cuddT(P), zvar);
31682  if (t == NULL) return(NULL);
31683  cuddRef(t);
31684  e = cuddZddChangeAux(zdd, cuddE(P), zvar);
31685  if (e == NULL) {
31686  Cudd_RecursiveDerefZdd(zdd, t);
31687  return(NULL);
31688  }
31689  cuddRef(e);
31690  res = cuddZddGetNode(zdd, P->index, t, e);
31691  if (res == NULL) {
31692  Cudd_RecursiveDerefZdd(zdd, t);
31693  Cudd_RecursiveDerefZdd(zdd, e);
31694  return(NULL);
31695  }
31696  cuddDeref(t);
31697  cuddDeref(e);
31698  }
31699 
31700  cuddCacheInsert2(zdd, cuddZddChangeAux, P, zvar, res);
31701 
31702  return(res);
31703 
31704 } /* end of cuddZddChangeAux */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
static DdNode * empty
Definition: cuddInt.c:28567
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddZddChangeAux(DdManager *zdd, DdNode *P, DdNode *zvar)
Definition: cuddInt.c:31650
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddInt.c:20408
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
#define DD_ONE(dd)
Definition: cuddInt.h:864
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddComplement()

DdNode* cuddZddComplement ( DdManager dd,
DdNode node 
)

Function********************************************************************

Synopsis [Computes a complement of a ZDD node.]

Description [Computes the complement of a ZDD node. So far, since we couldn't find a direct way to get the complement of a ZDD cover, we first convert a ZDD cover to a BDD, then make the complement of the ZDD cover from the complement of the BDD node by using ISOP.]

SideEffects [The result depends on current variable order.]

SeeAlso []

Definition at line 26289 of file cuddInt.c.

26292 {
26293  DdNode *b, *isop, *zdd_I;
26294 
26295  /* Check cache */
26296  zdd_I = cuddCacheLookup1Zdd(dd, cuddZddComplement, node);
26297  if (zdd_I)
26298  return(zdd_I);
26299 
26300  b = cuddMakeBddFromZddCover(dd, node);
26301  if (!b)
26302  return(NULL);
26303  cuddRef(b);
26304  isop = cuddZddIsop(dd, Cudd_Not(b), Cudd_Not(b), &zdd_I);
26305  if (!isop) {
26306  Cudd_RecursiveDeref(dd, b);
26307  return(NULL);
26308  }
26309  cuddRef(isop);
26310  cuddRef(zdd_I);
26311  Cudd_RecursiveDeref(dd, b);
26312  Cudd_RecursiveDeref(dd, isop);
26313 
26314  cuddCacheInsert1(dd, cuddZddComplement, node, zdd_I);
26315  cuddDeref(zdd_I);
26316  return(zdd_I);
26317 } /* end of cuddZddComplement */
void cuddCacheInsert1(DdManager *table, DD_CTFP1 op, DdNode *f, DdNode *data)
Definition: cuddInt.c:4371
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
DdNode * cuddCacheLookup1Zdd(DdManager *table, DD_CTFP1 op, DdNode *f)
Definition: cuddInt.c:4699
DdNode * cuddZddIsop(DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)
Definition: cuddInt.c:27794
DdNode * cuddZddComplement(DdManager *dd, DdNode *node)
Definition: cuddInt.c:26289
DdNode * cuddMakeBddFromZddCover(DdManager *dd, DdNode *node)
Definition: cuddInt.c:28360

◆ cuddZddDiff()

DdNode* cuddZddDiff ( DdManager zdd,
DdNode P,
DdNode Q 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddDiff.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 31568 of file cuddInt.c.

31572 {
31573  int p_top, q_top;
31574  DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
31575  DdManager *table = zdd;
31576 
31577  statLine(zdd);
31578  if (P == empty)
31579  return(empty);
31580  if (Q == empty)
31581  return(P);
31582  if (P == Q)
31583  return(empty);
31584 
31585  /* Check cache. The cache is shared by Cudd_zddDiffConst(). */
31586  res = cuddCacheLookup2Zdd(table, cuddZddDiff, P, Q);
31587  if (res != NULL && res != DD_NON_CONSTANT)
31588  return(res);
31589 
31590  if (cuddIsConstant(P))
31591  p_top = P->index;
31592  else
31593  p_top = zdd->permZ[P->index];
31594  if (cuddIsConstant(Q))
31595  q_top = Q->index;
31596  else
31597  q_top = zdd->permZ[Q->index];
31598  if (p_top < q_top) {
31599  e = cuddZddDiff(zdd, cuddE(P), Q);
31600  if (e == NULL) return(NULL);
31601  cuddRef(e);
31602  res = cuddZddGetNode(zdd, P->index, cuddT(P), e);
31603  if (res == NULL) {
31604  Cudd_RecursiveDerefZdd(table, e);
31605  return(NULL);
31606  }
31607  cuddDeref(e);
31608  } else if (p_top > q_top) {
31609  res = cuddZddDiff(zdd, P, cuddE(Q));
31610  if (res == NULL) return(NULL);
31611  } else {
31612  t = cuddZddDiff(zdd, cuddT(P), cuddT(Q));
31613  if (t == NULL) return(NULL);
31614  cuddRef(t);
31615  e = cuddZddDiff(zdd, cuddE(P), cuddE(Q));
31616  if (e == NULL) {
31617  Cudd_RecursiveDerefZdd(table, t);
31618  return(NULL);
31619  }
31620  cuddRef(e);
31621  res = cuddZddGetNode(zdd, P->index, t, e);
31622  if (res == NULL) {
31623  Cudd_RecursiveDerefZdd(table, t);
31624  Cudd_RecursiveDerefZdd(table, e);
31625  return(NULL);
31626  }
31627  cuddDeref(t);
31628  cuddDeref(e);
31629  }
31630 
31631  cuddCacheInsert2(table, cuddZddDiff, P, Q, res);
31632 
31633  return(res);
31634 
31635 } /* end of cuddZddDiff */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
static DdNode * empty
Definition: cuddInt.c:28567
int * permZ
Definition: cuddInt.h:370
DdNode * cuddZddDiff(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddInt.c:31568
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddInt.c:20408
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
#define DD_NON_CONSTANT
Definition: cuddInt.h:124
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddDivide()

DdNode* cuddZddDivide ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddDivide.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddDivide]

Definition at line 25926 of file cuddInt.c.

25930 {
25931  int v;
25932  DdNode *one = DD_ONE(dd);
25933  DdNode *zero = DD_ZERO(dd);
25934  DdNode *f0, *f1, *g0, *g1;
25935  DdNode *q, *r, *tmp;
25936  int flag;
25937 
25938  statLine(dd);
25939  if (g == one)
25940  return(f);
25941  if (f == zero || f == one)
25942  return(zero);
25943  if (f == g)
25944  return(one);
25945 
25946  /* Check cache. */
25947  r = cuddCacheLookup2Zdd(dd, cuddZddDivide, f, g);
25948  if (r)
25949  return(r);
25950 
25951  v = g->index;
25952 
25953  flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
25954  if (flag == 1)
25955  return(NULL);
25956  Cudd_Ref(f1);
25957  Cudd_Ref(f0);
25958  flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */
25959  if (flag == 1) {
25960  Cudd_RecursiveDerefZdd(dd, f1);
25961  Cudd_RecursiveDerefZdd(dd, f0);
25962  return(NULL);
25963  }
25964  Cudd_Ref(g1);
25965  Cudd_Ref(g0);
25966 
25967  r = cuddZddDivide(dd, f1, g1);
25968  if (r == NULL) {
25969  Cudd_RecursiveDerefZdd(dd, f1);
25970  Cudd_RecursiveDerefZdd(dd, f0);
25971  Cudd_RecursiveDerefZdd(dd, g1);
25972  Cudd_RecursiveDerefZdd(dd, g0);
25973  return(NULL);
25974  }
25975  Cudd_Ref(r);
25976 
25977  if (r != zero && g0 != zero) {
25978  tmp = r;
25979  q = cuddZddDivide(dd, f0, g0);
25980  if (q == NULL) {
25981  Cudd_RecursiveDerefZdd(dd, f1);
25982  Cudd_RecursiveDerefZdd(dd, f0);
25983  Cudd_RecursiveDerefZdd(dd, g1);
25984  Cudd_RecursiveDerefZdd(dd, g0);
25985  return(NULL);
25986  }
25987  Cudd_Ref(q);
25988  r = cuddZddIntersect(dd, r, q);
25989  if (r == NULL) {
25990  Cudd_RecursiveDerefZdd(dd, f1);
25991  Cudd_RecursiveDerefZdd(dd, f0);
25992  Cudd_RecursiveDerefZdd(dd, g1);
25993  Cudd_RecursiveDerefZdd(dd, g0);
25994  Cudd_RecursiveDerefZdd(dd, q);
25995  return(NULL);
25996  }
25997  Cudd_Ref(r);
25998  Cudd_RecursiveDerefZdd(dd, q);
25999  Cudd_RecursiveDerefZdd(dd, tmp);
26000  }
26001 
26002  Cudd_RecursiveDerefZdd(dd, f1);
26003  Cudd_RecursiveDerefZdd(dd, f0);
26004  Cudd_RecursiveDerefZdd(dd, g1);
26005  Cudd_RecursiveDerefZdd(dd, g0);
26006 
26007  cuddCacheInsert2(dd, cuddZddDivide, f, g, r);
26008  Cudd_Deref(r);
26009  return(r);
26010 
26011 } /* end of cuddZddDivide */
Definition: cudd.h:264
static DdNode * one
Definition: cuddInt.c:16562
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
void Cudd_Ref(DdNode *n)
Definition: cuddInt.c:14002
int cuddZddGetCofactors2(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0)
Definition: cuddInt.c:26254
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddInt.c:31493
DdNode * cuddZddDivide(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:25926
DdHalfWord index
Definition: cudd.h:265
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void Cudd_Deref(DdNode *node)
Definition: cuddInt.c:14198
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddDivideF()

DdNode* cuddZddDivideF ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddDivideF.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddDivideF]

Definition at line 26026 of file cuddInt.c.

26030 {
26031  int v;
26032  DdNode *one = DD_ONE(dd);
26033  DdNode *zero = DD_ZERO(dd);
26034  DdNode *f0, *f1, *g0, *g1;
26035  DdNode *q, *r, *tmp;
26036  int flag;
26037 
26038  statLine(dd);
26039  if (g == one)
26040  return(f);
26041  if (f == zero || f == one)
26042  return(zero);
26043  if (f == g)
26044  return(one);
26045 
26046  /* Check cache. */
26047  r = cuddCacheLookup2Zdd(dd, cuddZddDivideF, f, g);
26048  if (r)
26049  return(r);
26050 
26051  v = g->index;
26052 
26053  flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
26054  if (flag == 1)
26055  return(NULL);
26056  Cudd_Ref(f1);
26057  Cudd_Ref(f0);
26058  flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0); /* g1 != zero */
26059  if (flag == 1) {
26060  Cudd_RecursiveDerefZdd(dd, f1);
26061  Cudd_RecursiveDerefZdd(dd, f0);
26062  return(NULL);
26063  }
26064  Cudd_Ref(g1);
26065  Cudd_Ref(g0);
26066 
26067  r = cuddZddDivideF(dd, f1, g1);
26068  if (r == NULL) {
26069  Cudd_RecursiveDerefZdd(dd, f1);
26070  Cudd_RecursiveDerefZdd(dd, f0);
26071  Cudd_RecursiveDerefZdd(dd, g1);
26072  Cudd_RecursiveDerefZdd(dd, g0);
26073  return(NULL);
26074  }
26075  Cudd_Ref(r);
26076 
26077  if (r != zero && g0 != zero) {
26078  tmp = r;
26079  q = cuddZddDivideF(dd, f0, g0);
26080  if (q == NULL) {
26081  Cudd_RecursiveDerefZdd(dd, f1);
26082  Cudd_RecursiveDerefZdd(dd, f0);
26083  Cudd_RecursiveDerefZdd(dd, g1);
26084  Cudd_RecursiveDerefZdd(dd, g0);
26085  return(NULL);
26086  }
26087  Cudd_Ref(q);
26088  r = cuddZddIntersect(dd, r, q);
26089  if (r == NULL) {
26090  Cudd_RecursiveDerefZdd(dd, f1);
26091  Cudd_RecursiveDerefZdd(dd, f0);
26092  Cudd_RecursiveDerefZdd(dd, g1);
26093  Cudd_RecursiveDerefZdd(dd, g0);
26094  Cudd_RecursiveDerefZdd(dd, q);
26095  return(NULL);
26096  }
26097  Cudd_Ref(r);
26098  Cudd_RecursiveDerefZdd(dd, q);
26099  Cudd_RecursiveDerefZdd(dd, tmp);
26100  }
26101 
26102  Cudd_RecursiveDerefZdd(dd, f1);
26103  Cudd_RecursiveDerefZdd(dd, f0);
26104  Cudd_RecursiveDerefZdd(dd, g1);
26105  Cudd_RecursiveDerefZdd(dd, g0);
26106 
26107  cuddCacheInsert2(dd, cuddZddDivideF, f, g, r);
26108  Cudd_Deref(r);
26109  return(r);
26110 
26111 } /* end of cuddZddDivideF */
Definition: cudd.h:264
static DdNode * one
Definition: cuddInt.c:16562
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
void Cudd_Ref(DdNode *n)
Definition: cuddInt.c:14002
int cuddZddGetCofactors2(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0)
Definition: cuddInt.c:26254
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddInt.c:31493
DdHalfWord index
Definition: cudd.h:265
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void Cudd_Deref(DdNode *node)
Definition: cuddInt.c:14198
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddZddDivideF(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:26026
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddFreeUniv()

void cuddZddFreeUniv ( DdManager zdd)

Function********************************************************************

Synopsis [Frees the ZDD universe.]

Description [Frees the ZDD universe.]

SideEffects [None]

SeeAlso [cuddZddInitUniv]

Definition at line 10717 of file cuddInt.c.

10719 {
10720  if (zdd->univ) {
10721  Cudd_RecursiveDerefZdd(zdd, zdd->univ[0]);
10722  FREE(zdd->univ);
10723  }
10724 
10725 } /* end of cuddZddFreeUniv */
#define FREE(obj)
Definition: util.h:80
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
DdNode ** univ
Definition: cuddInt.h:375

◆ cuddZddGetCofactors2()

int cuddZddGetCofactors2 ( DdManager dd,
DdNode f,
int  v,
DdNode **  f1,
DdNode **  f0 
)

Function********************************************************************

Synopsis [Computes the two-way decomposition of f w.r.t. v.]

Description []

SideEffects [The results are returned in f1 and f0.]

SeeAlso [cuddZddGetCofactors3]

Definition at line 26254 of file cuddInt.c.

26260 {
26261  *f1 = cuddZddSubset1(dd, f, v);
26262  if (*f1 == NULL)
26263  return(1);
26264  *f0 = cuddZddSubset0(dd, f, v);
26265  if (*f0 == NULL) {
26266  Cudd_RecursiveDerefZdd(dd, *f1);
26267  return(1);
26268  }
26269  return(0);
26270 
26271 } /* end of cuddZddGetCofactors2 */
DdNode * cuddZddSubset0(DdManager *dd, DdNode *P, int var)
Definition: cuddInt.c:31774
DdNode * cuddZddSubset1(DdManager *dd, DdNode *P, int var)
Definition: cuddInt.c:31725
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145

◆ cuddZddGetCofactors3()

int cuddZddGetCofactors3 ( DdManager dd,
DdNode f,
int  v,
DdNode **  f1,
DdNode **  f0,
DdNode **  fd 
)

Function********************************************************************

Synopsis [Computes the three-way decomposition of f w.r.t. v.]

Description [Computes the three-way decomposition of function f (represented by a ZDD) wit respect to variable v. Returns 0 if successful; 1 otherwise.]

SideEffects [The results are returned in f1, f0, and fd.]

SeeAlso [cuddZddGetCofactors2]

Definition at line 26127 of file cuddInt.c.

26134 {
26135  DdNode *pc, *nc;
26136  DdNode *zero = DD_ZERO(dd);
26137  int top, hv, ht, pv, nv;
26138  int level;
26139 
26140  top = dd->permZ[f->index];
26141  level = dd->permZ[v];
26142  hv = level >> 1;
26143  ht = top >> 1;
26144 
26145  if (hv < ht) {
26146  *f1 = zero;
26147  *f0 = zero;
26148  *fd = f;
26149  }
26150  else {
26151  pv = cuddZddGetPosVarIndex(dd, v);
26152  nv = cuddZddGetNegVarIndex(dd, v);
26153 
26154  /* not to create intermediate ZDD node */
26155  if (cuddZddGetPosVarLevel(dd, v) < cuddZddGetNegVarLevel(dd, v)) {
26156  pc = cuddZddSubset1(dd, f, pv);
26157  if (pc == NULL)
26158  return(1);
26159  Cudd_Ref(pc);
26160  nc = cuddZddSubset0(dd, f, pv);
26161  if (nc == NULL) {
26162  Cudd_RecursiveDerefZdd(dd, pc);
26163  return(1);
26164  }
26165  Cudd_Ref(nc);
26166 
26167  *f1 = cuddZddSubset0(dd, pc, nv);
26168  if (*f1 == NULL) {
26169  Cudd_RecursiveDerefZdd(dd, pc);
26170  Cudd_RecursiveDerefZdd(dd, nc);
26171  return(1);
26172  }
26173  Cudd_Ref(*f1);
26174  *f0 = cuddZddSubset1(dd, nc, nv);
26175  if (*f0 == NULL) {
26176  Cudd_RecursiveDerefZdd(dd, pc);
26177  Cudd_RecursiveDerefZdd(dd, nc);
26178  Cudd_RecursiveDerefZdd(dd, *f1);
26179  return(1);
26180  }
26181  Cudd_Ref(*f0);
26182 
26183  *fd = cuddZddSubset0(dd, nc, nv);
26184  if (*fd == NULL) {
26185  Cudd_RecursiveDerefZdd(dd, pc);
26186  Cudd_RecursiveDerefZdd(dd, nc);
26187  Cudd_RecursiveDerefZdd(dd, *f1);
26188  Cudd_RecursiveDerefZdd(dd, *f0);
26189  return(1);
26190  }
26191  Cudd_Ref(*fd);
26192  } else {
26193  pc = cuddZddSubset1(dd, f, nv);
26194  if (pc == NULL)
26195  return(1);
26196  Cudd_Ref(pc);
26197  nc = cuddZddSubset0(dd, f, nv);
26198  if (nc == NULL) {
26199  Cudd_RecursiveDerefZdd(dd, pc);
26200  return(1);
26201  }
26202  Cudd_Ref(nc);
26203 
26204  *f0 = cuddZddSubset0(dd, pc, pv);
26205  if (*f0 == NULL) {
26206  Cudd_RecursiveDerefZdd(dd, pc);
26207  Cudd_RecursiveDerefZdd(dd, nc);
26208  return(1);
26209  }
26210  Cudd_Ref(*f0);
26211  *f1 = cuddZddSubset1(dd, nc, pv);
26212  if (*f1 == NULL) {
26213  Cudd_RecursiveDerefZdd(dd, pc);
26214  Cudd_RecursiveDerefZdd(dd, nc);
26215  Cudd_RecursiveDerefZdd(dd, *f0);
26216  return(1);
26217  }
26218  Cudd_Ref(*f1);
26219 
26220  *fd = cuddZddSubset0(dd, nc, pv);
26221  if (*fd == NULL) {
26222  Cudd_RecursiveDerefZdd(dd, pc);
26223  Cudd_RecursiveDerefZdd(dd, nc);
26224  Cudd_RecursiveDerefZdd(dd, *f1);
26225  Cudd_RecursiveDerefZdd(dd, *f0);
26226  return(1);
26227  }
26228  Cudd_Ref(*fd);
26229  }
26230 
26231  Cudd_RecursiveDerefZdd(dd, pc);
26232  Cudd_RecursiveDerefZdd(dd, nc);
26233  Cudd_Deref(*f1);
26234  Cudd_Deref(*f0);
26235  Cudd_Deref(*fd);
26236  }
26237  return(0);
26238 
26239 } /* end of cuddZddGetCofactors3 */
Definition: cudd.h:264
DdNode * cuddZddSubset0(DdManager *dd, DdNode *P, int var)
Definition: cuddInt.c:31774
int cuddZddGetPosVarIndex(DdManager *dd, int index)
Definition: cuddInt.c:26332
int * permZ
Definition: cuddInt.h:370
int cuddZddGetPosVarLevel(DdManager *dd, int index)
Definition: cuddInt.c:26374
void Cudd_Ref(DdNode *n)
Definition: cuddInt.c:14002
DdNode * cuddZddSubset1(DdManager *dd, DdNode *P, int var)
Definition: cuddInt.c:31725
DdHalfWord index
Definition: cudd.h:265
int cuddZddGetNegVarLevel(DdManager *dd, int index)
Definition: cuddInt.c:26395
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void Cudd_Deref(DdNode *node)
Definition: cuddInt.c:14198
static DdNode * zero
Definition: cuddInt.c:16562
int cuddZddGetNegVarIndex(DdManager *dd, int index)
Definition: cuddInt.c:26353
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddGetNegVarIndex()

int cuddZddGetNegVarIndex ( DdManager dd,
int  index 
)

Function********************************************************************

Synopsis [Returns the index of negative ZDD variable.]

Description [Returns the index of negative ZDD variable.]

SideEffects []

SeeAlso []

Definition at line 26353 of file cuddInt.c.

26356 {
26357  int nv = index | 0x1;
26358  return(nv);
26359 } /* end of cuddZddGetPosVarIndex */

◆ cuddZddGetNegVarLevel()

int cuddZddGetNegVarLevel ( DdManager dd,
int  index 
)

Function********************************************************************

Synopsis [Returns the level of negative ZDD variable.]

Description [Returns the level of negative ZDD variable.]

SideEffects []

SeeAlso []

Definition at line 26395 of file cuddInt.c.

26398 {
26399  int nv = cuddZddGetNegVarIndex(dd, index);
26400  return(dd->permZ[nv]);
26401 } /* end of cuddZddGetNegVarLevel */
int * permZ
Definition: cuddInt.h:370
int cuddZddGetNegVarIndex(DdManager *dd, int index)
Definition: cuddInt.c:26353

◆ cuddZddGetNode()

DdNode* cuddZddGetNode ( DdManager zdd,
int  id,
DdNode T,
DdNode E 
)

Function********************************************************************

Synopsis [Wrapper for cuddUniqueInterZdd.]

Description [Wrapper for cuddUniqueInterZdd, which applies the ZDD reduction rule. Returns a pointer to the result node under normal conditions; NULL if reordering occurred or memory was exhausted.]

SideEffects [None]

SeeAlso [cuddUniqueInterZdd]

Definition at line 20408 of file cuddInt.c.

20413 {
20414 DdNode *node;
20415 
20416 if (T == DD_ZERO(zdd))
20417 return(E);
20418 node = cuddUniqueInterZdd(zdd, id, T, E);
20419 return(node);
20420 
20421 } /* end of cuddZddGetNode */
Definition: cudd.h:264
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20730
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddGetNodeIVO()

DdNode* cuddZddGetNodeIVO ( DdManager dd,
int  index,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Wrapper for cuddUniqueInterZdd that is independent of variable ordering.]

Description [Wrapper for cuddUniqueInterZdd that is independent of variable ordering (IVO). This function does not require parameter index to precede the indices of the top nodes of g and h in the variable order. Returns a pointer to the result node under normal conditions; NULL if reordering occurred or memory was exhausted.]

SideEffects [None]

SeeAlso [cuddZddGetNode cuddZddIsop]

Definition at line 20441 of file cuddInt.c.

20446 {
20447 DdNode *f, *r, *t;
20448 DdNode *zdd_one = DD_ONE(dd);
20449 DdNode *zdd_zero = DD_ZERO(dd);
20450 
20451 f = cuddUniqueInterZdd(dd, index, zdd_one, zdd_zero);
20452 if (f == NULL) {
20453 return(NULL);
20454 }
20455 cuddRef(f);
20456 t = cuddZddProduct(dd, f, g);
20457 if (t == NULL) {
20458 Cudd_RecursiveDerefZdd(dd, f);
20459 return(NULL);
20460 }
20461 cuddRef(t);
20462 Cudd_RecursiveDerefZdd(dd, f);
20463 r = cuddZddUnion(dd, t, h);
20464 if (r == NULL) {
20465 Cudd_RecursiveDerefZdd(dd, t);
20466 return(NULL);
20467 }
20468 cuddRef(r);
20469 Cudd_RecursiveDerefZdd(dd, t);
20470 
20471 cuddDeref(r);
20472 return(r);
20473 
20474 } /* end of cuddZddGetNodeIVO */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddInt.c:31404
DdNode * cuddZddProduct(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:25147
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20730
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddGetPosVarIndex()

int cuddZddGetPosVarIndex ( DdManager dd,
int  index 
)

Function********************************************************************

Synopsis [Returns the index of positive ZDD variable.]

Description [Returns the index of positive ZDD variable.]

SideEffects []

SeeAlso []

Definition at line 26332 of file cuddInt.c.

26335 {
26336  int pv = (index >> 1) << 1;
26337  return(pv);
26338 } /* end of cuddZddGetPosVarIndex */

◆ cuddZddGetPosVarLevel()

int cuddZddGetPosVarLevel ( DdManager dd,
int  index 
)

Function********************************************************************

Synopsis [Returns the level of positive ZDD variable.]

Description [Returns the level of positive ZDD variable.]

SideEffects []

SeeAlso []

Definition at line 26374 of file cuddInt.c.

26377 {
26378  int pv = cuddZddGetPosVarIndex(dd, index);
26379  return(dd->permZ[pv]);
26380 } /* end of cuddZddGetPosVarLevel */
int cuddZddGetPosVarIndex(DdManager *dd, int index)
Definition: cuddInt.c:26332
int * permZ
Definition: cuddInt.h:370

◆ cuddZddInitUniv()

int cuddZddInitUniv ( DdManager zdd)

Function********************************************************************

Synopsis [Initializes the ZDD universe.]

Description [Initializes the ZDD universe. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddZddFreeUniv]

Definition at line 10668 of file cuddInt.c.

10670 {
10671  DdNode *p, *res;
10672  int i;
10673 
10674  zdd->univ = ALLOC(DdNodePtr, zdd->sizeZ);
10675  if (zdd->univ == NULL) {
10676  zdd->errorCode = CUDD_MEMORY_OUT;
10677  return(0);
10678  }
10679 
10680  res = DD_ONE(zdd);
10681  cuddRef(res);
10682  for (i = zdd->sizeZ - 1; i >= 0; i--) {
10683  unsigned int index = zdd->invpermZ[i];
10684  p = res;
10685  res = cuddUniqueInterZdd(zdd, index, p, p);
10686  if (res == NULL) {
10687  Cudd_RecursiveDerefZdd(zdd,p);
10688  FREE(zdd->univ);
10689  return(0);
10690  }
10691  cuddRef(res);
10692  cuddDeref(p);
10693  zdd->univ[i] = res;
10694  }
10695 
10696 #ifdef DD_VERBOSE
10697  cuddZddP(zdd, zdd->univ[0]);
10698 #endif
10699 
10700  return(1);
10701 
10702 } /* end of cuddZddInitUniv */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
int * invpermZ
Definition: cuddInt.h:372
#define ALLOC(type, num)
Definition: util.h:76
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20730
int sizeZ
Definition: cuddInt.h:346
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
#define DD_ONE(dd)
Definition: cuddInt.h:864
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
int cuddZddP(DdManager *zdd, DdNode *f)
DdNode ** univ
Definition: cuddInt.h:375

◆ cuddZddIntersect()

DdNode* cuddZddIntersect ( DdManager zdd,
DdNode P,
DdNode Q 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddIntersect.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 31493 of file cuddInt.c.

31497 {
31498  int p_top, q_top;
31499  DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
31500  DdManager *table = zdd;
31501 
31502  statLine(zdd);
31503  if (P == empty)
31504  return(empty);
31505  if (Q == empty)
31506  return(empty);
31507  if (P == Q)
31508  return(P);
31509 
31510  /* Check cache. */
31511  res = cuddCacheLookup2Zdd(table, cuddZddIntersect, P, Q);
31512  if (res != NULL)
31513  return(res);
31514 
31515  if (cuddIsConstant(P))
31516  p_top = P->index;
31517  else
31518  p_top = zdd->permZ[P->index];
31519  if (cuddIsConstant(Q))
31520  q_top = Q->index;
31521  else
31522  q_top = zdd->permZ[Q->index];
31523  if (p_top < q_top) {
31524  res = cuddZddIntersect(zdd, cuddE(P), Q);
31525  if (res == NULL) return(NULL);
31526  } else if (p_top > q_top) {
31527  res = cuddZddIntersect(zdd, P, cuddE(Q));
31528  if (res == NULL) return(NULL);
31529  } else {
31530  t = cuddZddIntersect(zdd, cuddT(P), cuddT(Q));
31531  if (t == NULL) return(NULL);
31532  cuddRef(t);
31533  e = cuddZddIntersect(zdd, cuddE(P), cuddE(Q));
31534  if (e == NULL) {
31535  Cudd_RecursiveDerefZdd(table, t);
31536  return(NULL);
31537  }
31538  cuddRef(e);
31539  res = cuddZddGetNode(zdd, P->index, t, e);
31540  if (res == NULL) {
31541  Cudd_RecursiveDerefZdd(table, t);
31542  Cudd_RecursiveDerefZdd(table, e);
31543  return(NULL);
31544  }
31545  cuddDeref(t);
31546  cuddDeref(e);
31547  }
31548 
31549  cuddCacheInsert2(table, cuddZddIntersect, P, Q, res);
31550 
31551  return(res);
31552 
31553 } /* end of cuddZddIntersect */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
static DdNode * empty
Definition: cuddInt.c:28567
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddInt.c:31493
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddInt.c:20408
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddIsop()

DdNode* cuddZddIsop ( DdManager dd,
DdNode L,
DdNode U,
DdNode **  zdd_I 
)

CFile***********************************************************************

FileName [cuddZddIsop.c]

PackageName [cudd]

Synopsis [Functions to find irredundant SOP covers as ZDDs from BDDs.]

Description [External procedures included in this module:

  • Cudd_bddIsop()
  • Cudd_zddIsop()
  • Cudd_MakeBddFromZddCover()

Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso []

Author [In-Ho Moon]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddIsop.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddIsop]

Definition at line 27794 of file cuddInt.c.

27799 {
27800  DdNode *one = DD_ONE(dd);
27801  DdNode *zero = Cudd_Not(one);
27802  DdNode *zdd_one = DD_ONE(dd);
27803  DdNode *zdd_zero = DD_ZERO(dd);
27804  int v, top_l, top_u;
27805  DdNode *Lsub0, *Usub0, *Lsub1, *Usub1, *Ld, *Ud;
27806  DdNode *Lsuper0, *Usuper0, *Lsuper1, *Usuper1;
27807  DdNode *Isub0, *Isub1, *Id;
27808  DdNode *zdd_Isub0, *zdd_Isub1, *zdd_Id;
27809  DdNode *x;
27810  DdNode *term0, *term1, *sum;
27811  DdNode *Lv, *Uv, *Lnv, *Unv;
27812  DdNode *r, *y, *z;
27813  int index;
27814  DD_CTFP cacheOp;
27815 
27816  statLine(dd);
27817  if (L == zero) {
27818  *zdd_I = zdd_zero;
27819  return(zero);
27820  }
27821  if (U == one) {
27822  *zdd_I = zdd_one;
27823  return(one);
27824  }
27825 
27826  if (U == zero || L == one) {
27827  printf("*** ERROR : illegal condition for ISOP (U < L).\n");
27828  exit(1);
27829  }
27830 
27831  /* Check the cache. We store two results for each recursive call.
27832  ** One is the BDD, and the other is the ZDD. Both are needed.
27833  ** Hence we need a double hit in the cache to terminate the
27834  ** recursion. Clearly, collisions may evict only one of the two
27835  ** results. */
27836  cacheOp = (DD_CTFP) cuddZddIsop;
27837  r = cuddCacheLookup2(dd, cuddBddIsop, L, U);
27838  if (r) {
27839  *zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U);
27840  if (*zdd_I)
27841  return(r);
27842  else {
27843  /* The BDD result may have been dead. In that case
27844  ** cuddCacheLookup2 would have called cuddReclaim,
27845  ** whose effects we now have to undo. */
27846  cuddRef(r);
27847  Cudd_RecursiveDeref(dd, r);
27848  }
27849  }
27850 
27851  top_l = dd->perm[Cudd_Regular(L)->index];
27852  top_u = dd->perm[Cudd_Regular(U)->index];
27853  v = ddMin(top_l, top_u);
27854 
27855  /* Compute cofactors. */
27856  if (top_l == v) {
27857  index = Cudd_Regular(L)->index;
27858  Lv = Cudd_T(L);
27859  Lnv = Cudd_E(L);
27860  if (Cudd_IsComplement(L)) {
27861  Lv = Cudd_Not(Lv);
27862  Lnv = Cudd_Not(Lnv);
27863  }
27864  }
27865  else {
27866  index = Cudd_Regular(U)->index;
27867  Lv = Lnv = L;
27868  }
27869 
27870  if (top_u == v) {
27871  Uv = Cudd_T(U);
27872  Unv = Cudd_E(U);
27873  if (Cudd_IsComplement(U)) {
27874  Uv = Cudd_Not(Uv);
27875  Unv = Cudd_Not(Unv);
27876  }
27877  }
27878  else {
27879  Uv = Unv = U;
27880  }
27881 
27882  Lsub0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Uv));
27883  if (Lsub0 == NULL)
27884  return(NULL);
27885  Cudd_Ref(Lsub0);
27886  Usub0 = Unv;
27887  Lsub1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Unv));
27888  if (Lsub1 == NULL) {
27889  Cudd_RecursiveDeref(dd, Lsub0);
27890  return(NULL);
27891  }
27892  Cudd_Ref(Lsub1);
27893  Usub1 = Uv;
27894 
27895  Isub0 = cuddZddIsop(dd, Lsub0, Usub0, &zdd_Isub0);
27896  if (Isub0 == NULL) {
27897  Cudd_RecursiveDeref(dd, Lsub0);
27898  Cudd_RecursiveDeref(dd, Lsub1);
27899  return(NULL);
27900  }
27901  /*
27902  if ((!cuddIsConstant(Cudd_Regular(Isub0))) &&
27903  (Cudd_Regular(Isub0)->index != zdd_Isub0->index / 2 ||
27904  dd->permZ[index * 2] > dd->permZ[zdd_Isub0->index])) {
27905  printf("*** ERROR : illegal permutation in ZDD. ***\n");
27906  }
27907  */
27908  Cudd_Ref(Isub0);
27909  Cudd_Ref(zdd_Isub0);
27910  Isub1 = cuddZddIsop(dd, Lsub1, Usub1, &zdd_Isub1);
27911  if (Isub1 == NULL) {
27912  Cudd_RecursiveDeref(dd, Lsub0);
27913  Cudd_RecursiveDeref(dd, Lsub1);
27914  Cudd_RecursiveDeref(dd, Isub0);
27915  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
27916  return(NULL);
27917  }
27918  /*
27919  if ((!cuddIsConstant(Cudd_Regular(Isub1))) &&
27920  (Cudd_Regular(Isub1)->index != zdd_Isub1->index / 2 ||
27921  dd->permZ[index * 2] > dd->permZ[zdd_Isub1->index])) {
27922  printf("*** ERROR : illegal permutation in ZDD. ***\n");
27923  }
27924  */
27925  Cudd_Ref(Isub1);
27926  Cudd_Ref(zdd_Isub1);
27927  Cudd_RecursiveDeref(dd, Lsub0);
27928  Cudd_RecursiveDeref(dd, Lsub1);
27929 
27930  Lsuper0 = cuddBddAndRecur(dd, Lnv, Cudd_Not(Isub0));
27931  if (Lsuper0 == NULL) {
27932  Cudd_RecursiveDeref(dd, Isub0);
27933  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
27934  Cudd_RecursiveDeref(dd, Isub1);
27935  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
27936  return(NULL);
27937  }
27938  Cudd_Ref(Lsuper0);
27939  Lsuper1 = cuddBddAndRecur(dd, Lv, Cudd_Not(Isub1));
27940  if (Lsuper1 == NULL) {
27941  Cudd_RecursiveDeref(dd, Isub0);
27942  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
27943  Cudd_RecursiveDeref(dd, Isub1);
27944  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
27945  Cudd_RecursiveDeref(dd, Lsuper0);
27946  return(NULL);
27947  }
27948  Cudd_Ref(Lsuper1);
27949  Usuper0 = Unv;
27950  Usuper1 = Uv;
27951 
27952  /* Ld = Lsuper0 + Lsuper1 */
27953  Ld = cuddBddAndRecur(dd, Cudd_Not(Lsuper0), Cudd_Not(Lsuper1));
27954  if (Ld == NULL) {
27955  Cudd_RecursiveDeref(dd, Isub0);
27956  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
27957  Cudd_RecursiveDeref(dd, Isub1);
27958  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
27959  Cudd_RecursiveDeref(dd, Lsuper0);
27960  Cudd_RecursiveDeref(dd, Lsuper1);
27961  return(NULL);
27962  }
27963  Ld = Cudd_Not(Ld);
27964  Cudd_Ref(Ld);
27965  /* Ud = Usuper0 * Usuper1 */
27966  Ud = cuddBddAndRecur(dd, Usuper0, Usuper1);
27967  if (Ud == NULL) {
27968  Cudd_RecursiveDeref(dd, Isub0);
27969  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
27970  Cudd_RecursiveDeref(dd, Isub1);
27971  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
27972  Cudd_RecursiveDeref(dd, Lsuper0);
27973  Cudd_RecursiveDeref(dd, Lsuper1);
27974  Cudd_RecursiveDeref(dd, Ld);
27975  return(NULL);
27976  }
27977  Cudd_Ref(Ud);
27978  Cudd_RecursiveDeref(dd, Lsuper0);
27979  Cudd_RecursiveDeref(dd, Lsuper1);
27980 
27981  Id = cuddZddIsop(dd, Ld, Ud, &zdd_Id);
27982  if (Id == NULL) {
27983  Cudd_RecursiveDeref(dd, Isub0);
27984  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
27985  Cudd_RecursiveDeref(dd, Isub1);
27986  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
27987  Cudd_RecursiveDeref(dd, Ld);
27988  Cudd_RecursiveDeref(dd, Ud);
27989  return(NULL);
27990  }
27991  /*
27992  if ((!cuddIsConstant(Cudd_Regular(Id))) &&
27993  (Cudd_Regular(Id)->index != zdd_Id->index / 2 ||
27994  dd->permZ[index * 2] > dd->permZ[zdd_Id->index])) {
27995  printf("*** ERROR : illegal permutation in ZDD. ***\n");
27996  }
27997  */
27998  Cudd_Ref(Id);
27999  Cudd_Ref(zdd_Id);
28000  Cudd_RecursiveDeref(dd, Ld);
28001  Cudd_RecursiveDeref(dd, Ud);
28002 
28003  x = cuddUniqueInter(dd, index, one, zero);
28004  if (x == NULL) {
28005  Cudd_RecursiveDeref(dd, Isub0);
28006  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
28007  Cudd_RecursiveDeref(dd, Isub1);
28008  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
28009  Cudd_RecursiveDeref(dd, Id);
28010  Cudd_RecursiveDerefZdd(dd, zdd_Id);
28011  return(NULL);
28012  }
28013  Cudd_Ref(x);
28014  /* term0 = x * Isub0 */
28015  term0 = cuddBddAndRecur(dd, Cudd_Not(x), Isub0);
28016  if (term0 == NULL) {
28017  Cudd_RecursiveDeref(dd, Isub0);
28018  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
28019  Cudd_RecursiveDeref(dd, Isub1);
28020  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
28021  Cudd_RecursiveDeref(dd, Id);
28022  Cudd_RecursiveDerefZdd(dd, zdd_Id);
28023  Cudd_RecursiveDeref(dd, x);
28024  return(NULL);
28025  }
28026  Cudd_Ref(term0);
28027  Cudd_RecursiveDeref(dd, Isub0);
28028  /* term1 = x * Isub1 */
28029  term1 = cuddBddAndRecur(dd, x, Isub1);
28030  if (term1 == NULL) {
28031  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
28032  Cudd_RecursiveDeref(dd, Isub1);
28033  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
28034  Cudd_RecursiveDeref(dd, Id);
28035  Cudd_RecursiveDerefZdd(dd, zdd_Id);
28036  Cudd_RecursiveDeref(dd, x);
28037  Cudd_RecursiveDeref(dd, term0);
28038  return(NULL);
28039  }
28040  Cudd_Ref(term1);
28041  Cudd_RecursiveDeref(dd, x);
28042  Cudd_RecursiveDeref(dd, Isub1);
28043  /* sum = term0 + term1 */
28044  sum = cuddBddAndRecur(dd, Cudd_Not(term0), Cudd_Not(term1));
28045  if (sum == NULL) {
28046  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
28047  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
28048  Cudd_RecursiveDeref(dd, Id);
28049  Cudd_RecursiveDerefZdd(dd, zdd_Id);
28050  Cudd_RecursiveDeref(dd, term0);
28051  Cudd_RecursiveDeref(dd, term1);
28052  return(NULL);
28053  }
28054  sum = Cudd_Not(sum);
28055  Cudd_Ref(sum);
28056  Cudd_RecursiveDeref(dd, term0);
28057  Cudd_RecursiveDeref(dd, term1);
28058  /* r = sum + Id */
28059  r = cuddBddAndRecur(dd, Cudd_Not(sum), Cudd_Not(Id));
28060  r = Cudd_NotCond(r, r != NULL);
28061  if (r == NULL) {
28062  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
28063  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
28064  Cudd_RecursiveDeref(dd, Id);
28065  Cudd_RecursiveDerefZdd(dd, zdd_Id);
28066  Cudd_RecursiveDeref(dd, sum);
28067  return(NULL);
28068  }
28069  Cudd_Ref(r);
28070  Cudd_RecursiveDeref(dd, sum);
28071  Cudd_RecursiveDeref(dd, Id);
28072 
28073  if (zdd_Isub0 != zdd_zero) {
28074  z = cuddZddGetNodeIVO(dd, index * 2 + 1, zdd_Isub0, zdd_Id);
28075  if (z == NULL) {
28076  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
28077  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
28078  Cudd_RecursiveDerefZdd(dd, zdd_Id);
28079  Cudd_RecursiveDeref(dd, r);
28080  return(NULL);
28081  }
28082  }
28083  else {
28084  z = zdd_Id;
28085  }
28086  Cudd_Ref(z);
28087  if (zdd_Isub1 != zdd_zero) {
28088  y = cuddZddGetNodeIVO(dd, index * 2, zdd_Isub1, z);
28089  if (y == NULL) {
28090  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
28091  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
28092  Cudd_RecursiveDerefZdd(dd, zdd_Id);
28093  Cudd_RecursiveDeref(dd, r);
28094  Cudd_RecursiveDerefZdd(dd, z);
28095  return(NULL);
28096  }
28097  }
28098  else
28099  y = z;
28100  Cudd_Ref(y);
28101 
28102  Cudd_RecursiveDerefZdd(dd, zdd_Isub0);
28103  Cudd_RecursiveDerefZdd(dd, zdd_Isub1);
28104  Cudd_RecursiveDerefZdd(dd, zdd_Id);
28105  Cudd_RecursiveDerefZdd(dd, z);
28106 
28107  cuddCacheInsert2(dd, cuddBddIsop, L, U, r);
28108  cuddCacheInsert2(dd, cacheOp, L, U, y);
28109 
28110  Cudd_Deref(r);
28111  Cudd_Deref(y);
28112  *zdd_I = y;
28113  /*
28114  if (Cudd_Regular(r)->index != y->index / 2) {
28115  printf("*** ERROR : mismatch in indices between BDD and ZDD. ***\n");
28116  }
28117  */
28118  return(r);
28119 
28120 } /* end of cuddZddIsop */
#define cuddRef(n)
Definition: cuddInt.h:557
#define Cudd_T(node)
Definition: cudd.h:416
VOID_OR_INT exit()
#define Cudd_E(node)
Definition: cudd.h:431
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
DdNode * cuddBddIsop(DdManager *dd, DdNode *L, DdNode *U)
Definition: cuddInt.c:28135
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode *(* DD_CTFP)(DdManager *, DdNode *, DdNode *)
Definition: cudd.h:297
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
DdNode * cuddCacheLookup2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4537
void Cudd_Ref(DdNode *n)
Definition: cuddInt.c:14002
#define ddMin(x, y)
Definition: cuddInt.h:771
DdNode * cuddZddIsop(DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)
Definition: cuddInt.c:27794
#define Cudd_NotCond(node, c)
Definition: cudd.h:359
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void Cudd_Deref(DdNode *node)
Definition: cuddInt.c:14198
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633
int * perm
Definition: cuddInt.h:369
DdNode * cuddZddGetNodeIVO(DdManager *dd, int index, DdNode *g, DdNode *h)
Definition: cuddInt.c:20441
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddIte()

DdNode* cuddZddIte ( DdManager dd,
DdNode f,
DdNode g,
DdNode h 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddIte.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 31278 of file cuddInt.c.

31283 {
31284  DdNode *tautology, *empty;
31285  DdNode *r,*Gv,*Gvn,*Hv,*Hvn,*t,*e;
31286  unsigned int topf,topg,toph,v,top;
31287  int index;
31288 
31289  statLine(dd);
31290  /* Trivial cases. */
31291  /* One variable cases. */
31292  if (f == (empty = DD_ZERO(dd))) { /* ITE(0,G,H) = H */
31293  return(h);
31294  }
31295  topf = cuddIZ(dd,f->index);
31296  topg = cuddIZ(dd,g->index);
31297  toph = cuddIZ(dd,h->index);
31298  v = ddMin(topg,toph);
31299  top = ddMin(topf,v);
31300 
31301  tautology = (top == CUDD_MAXINDEX) ? DD_ONE(dd) : dd->univ[top];
31302  if (f == tautology) { /* ITE(1,G,H) = G */
31303  return(g);
31304  }
31305 
31306  /* From now on, f is known to not be a constant. */
31307  zddVarToConst(f,&g,&h,tautology,empty);
31308 
31309  /* Check remaining one variable cases. */
31310  if (g == h) { /* ITE(F,G,G) = G */
31311  return(g);
31312  }
31313 
31314  if (g == tautology) { /* ITE(F,1,0) = F */
31315  if (h == empty) return(f);
31316  }
31317 
31318  /* Check cache. */
31319  r = cuddCacheLookupZdd(dd,DD_ZDD_ITE_TAG,f,g,h);
31320  if (r != NULL) {
31321  return(r);
31322  }
31323 
31324  /* Recompute these because they may have changed in zddVarToConst. */
31325  topg = cuddIZ(dd,g->index);
31326  toph = cuddIZ(dd,h->index);
31327  v = ddMin(topg,toph);
31328 
31329  if (topf < v) {
31330  r = cuddZddIte(dd,cuddE(f),g,h);
31331  if (r == NULL) return(NULL);
31332  } else if (topf > v) {
31333  if (topg > v) {
31334  Gvn = g;
31335  index = h->index;
31336  } else {
31337  Gvn = cuddE(g);
31338  index = g->index;
31339  }
31340  if (toph > v) {
31341  Hv = empty; Hvn = h;
31342  } else {
31343  Hv = cuddT(h); Hvn = cuddE(h);
31344  }
31345  e = cuddZddIte(dd,f,Gvn,Hvn);
31346  if (e == NULL) return(NULL);
31347  cuddRef(e);
31348  r = cuddZddGetNode(dd,index,Hv,e);
31349  if (r == NULL) {
31350  Cudd_RecursiveDerefZdd(dd,e);
31351  return(NULL);
31352  }
31353  cuddDeref(e);
31354  } else {
31355  index = f->index;
31356  if (topg > v) {
31357  Gv = empty; Gvn = g;
31358  } else {
31359  Gv = cuddT(g); Gvn = cuddE(g);
31360  }
31361  if (toph > v) {
31362  Hv = empty; Hvn = h;
31363  } else {
31364  Hv = cuddT(h); Hvn = cuddE(h);
31365  }
31366  e = cuddZddIte(dd,cuddE(f),Gvn,Hvn);
31367  if (e == NULL) return(NULL);
31368  cuddRef(e);
31369  t = cuddZddIte(dd,cuddT(f),Gv,Hv);
31370  if (t == NULL) {
31371  Cudd_RecursiveDerefZdd(dd,e);
31372  return(NULL);
31373  }
31374  cuddRef(t);
31375  r = cuddZddGetNode(dd,index,t,e);
31376  if (r == NULL) {
31377  Cudd_RecursiveDerefZdd(dd,e);
31378  Cudd_RecursiveDerefZdd(dd,t);
31379  return(NULL);
31380  }
31381  cuddDeref(t);
31382  cuddDeref(e);
31383  }
31384 
31385  cuddCacheInsert(dd,DD_ZDD_ITE_TAG,f,g,h,r);
31386 
31387  return(r);
31388 
31389 } /* end of cuddZddIte */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
#define cuddIZ(dd, index)
Definition: cuddInt.h:677
Definition: cudd.h:264
DdNode * cuddCacheLookupZdd(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:4475
static DdNode * empty
Definition: cuddInt.c:28567
#define statLine(dd)
Definition: cuddInt.h:990
static void zddVarToConst(DdNode *f, DdNode **gp, DdNode **hp, DdNode *base, DdNode *empty)
Definition: cuddInt.c:31961
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#define DD_ZDD_ITE_TAG
Definition: cuddInt.h:184
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddInt.c:20408
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddInt.c:4283
DdHalfWord index
Definition: cudd.h:265
#define CUDD_MAXINDEX
Definition: cudd.h:102
#define cuddE(node)
Definition: cuddInt.h:625
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddZddIte(DdManager *dd, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:31278
DdNode ** univ
Definition: cuddInt.h:375
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddLinearAux()

static int cuddZddLinearAux ( DdManager table,
int  x,
int  xLow,
int  xHigh 
)
static

Function********************************************************************

Synopsis [Given xLow <= x <= xHigh moves x up and down between the boundaries.]

Description [Given xLow <= x <= xHigh moves x up and down between the boundaries. Finds the best position and does the required changes. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 29050 of file cuddInt.c.

29055 {
29056  Move *move;
29057  Move *moveUp; /* list of up move */
29058  Move *moveDown; /* list of down move */
29059 
29060  int initial_size;
29061  int result;
29062 
29063  initial_size = table->keysZ;
29064 
29065 #ifdef DD_DEBUG
29066  assert(table->subtableZ[x].keys > 0);
29067 #endif
29068 
29069  moveDown = NULL;
29070  moveUp = NULL;
29071 
29072  if (x == xLow) {
29073  moveDown = cuddZddLinearDown(table, x, xHigh, NULL);
29074  /* At this point x --> xHigh. */
29075  if (moveDown == (Move *) CUDD_OUT_OF_MEM)
29076  goto cuddZddLinearAuxOutOfMem;
29077  /* Move backward and stop at best position. */
29078  result = cuddZddLinearBackward(table, initial_size, moveDown);
29079  if (!result)
29080  goto cuddZddLinearAuxOutOfMem;
29081 
29082  } else if (x == xHigh) {
29083  moveUp = cuddZddLinearUp(table, x, xLow, NULL);
29084  /* At this point x --> xLow. */
29085  if (moveUp == (Move *) CUDD_OUT_OF_MEM)
29086  goto cuddZddLinearAuxOutOfMem;
29087  /* Move backward and stop at best position. */
29088  result = cuddZddLinearBackward(table, initial_size, moveUp);
29089  if (!result)
29090  goto cuddZddLinearAuxOutOfMem;
29091 
29092  } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */
29093  moveDown = cuddZddLinearDown(table, x, xHigh, NULL);
29094  /* At this point x --> xHigh. */
29095  if (moveDown == (Move *) CUDD_OUT_OF_MEM)
29096  goto cuddZddLinearAuxOutOfMem;
29097  moveUp = cuddZddUndoMoves(table,moveDown);
29098 #ifdef DD_DEBUG
29099  assert(moveUp == NULL || moveUp->x == x);
29100 #endif
29101  moveUp = cuddZddLinearUp(table, x, xLow, moveUp);
29102  if (moveUp == (Move *) CUDD_OUT_OF_MEM)
29103  goto cuddZddLinearAuxOutOfMem;
29104  /* Move backward and stop at best position. */
29105  result = cuddZddLinearBackward(table, initial_size, moveUp);
29106  if (!result)
29107  goto cuddZddLinearAuxOutOfMem;
29108 
29109  } else {
29110  moveUp = cuddZddLinearUp(table, x, xLow, NULL);
29111  /* At this point x --> xHigh. */
29112  if (moveUp == (Move *) CUDD_OUT_OF_MEM)
29113  goto cuddZddLinearAuxOutOfMem;
29114  /* Then move up. */
29115  moveDown = cuddZddUndoMoves(table,moveUp);
29116 #ifdef DD_DEBUG
29117  assert(moveDown == NULL || moveDown->y == x);
29118 #endif
29119  moveDown = cuddZddLinearDown(table, x, xHigh, moveDown);
29120  if (moveDown == (Move *) CUDD_OUT_OF_MEM)
29121  goto cuddZddLinearAuxOutOfMem;
29122  /* Move backward and stop at best position. */
29123  result = cuddZddLinearBackward(table, initial_size, moveDown);
29124  if (!result)
29125  goto cuddZddLinearAuxOutOfMem;
29126  }
29127 
29128  while (moveDown != NULL) {
29129  move = moveDown->next;
29130  cuddDeallocMove(table, moveDown);
29131  moveDown = move;
29132  }
29133  while (moveUp != NULL) {
29134  move = moveUp->next;
29135  cuddDeallocMove(table, moveUp);
29136  moveUp = move;
29137  }
29138 
29139  return(1);
29140 
29141  cuddZddLinearAuxOutOfMem:
29142  if (moveDown != (Move *) CUDD_OUT_OF_MEM) {
29143  while (moveDown != NULL) {
29144  move = moveDown->next;
29145  cuddDeallocMove(table, moveDown);
29146  moveDown = move;
29147  }
29148  }
29149  if (moveUp != (Move *) CUDD_OUT_OF_MEM) {
29150  while (moveUp != NULL) {
29151  move = moveUp->next;
29152  cuddDeallocMove(table, moveUp);
29153  moveUp = move;
29154  }
29155  }
29156 
29157  return(0);
29158 
29159 } /* end of cuddZddLinearAux */
unsigned int keys
Definition: cuddInt.h:314
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
static Move * cuddZddUndoMoves(DdManager *table, Move *moves)
Definition: cuddInt.c:29394
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
static Move * cuddZddLinearUp(DdManager *table, int y, int xLow, Move *prevMoves)
Definition: cuddInt.c:29177
DdHalfWord x
Definition: cuddInt.h:470
static int cuddZddLinearBackward(DdManager *table, int size, Move *moves)
Definition: cuddInt.c:29346
static int result
Definition: cuddInt.c:7466
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
static Move * cuddZddLinearDown(DdManager *table, int x, int xHigh, Move *prevMoves)
Definition: cuddInt.c:29262
unsigned int keysZ
Definition: cuddInt.h:354
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddLinearBackward()

static int cuddZddLinearBackward ( DdManager table,
int  size,
Move moves 
)
static

Function********************************************************************

Synopsis [Given a set of moves, returns the ZDD heap to the position giving the minimum size.]

Description [Given a set of moves, returns the ZDD heap to the position giving the minimum size. In case of ties, returns to the closest position giving the minimum size. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 29346 of file cuddInt.c.

29350 {
29351  Move *move;
29352  int res;
29353 
29354  /* Find the minimum size among moves. */
29355  for (move = moves; move != NULL; move = move->next) {
29356  if (move->size < size) {
29357  size = move->size;
29358  }
29359  }
29360 
29361  for (move = moves; move != NULL; move = move->next) {
29362  if (move->size == size) return(1);
29363  if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) {
29364  res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y);
29365  if (!res) return(0);
29366  }
29367  res = cuddZddSwapInPlace(table, move->x, move->y);
29368  if (!res)
29369  return(0);
29370  if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) {
29371  res = cuddZddLinearInPlace(table,(int)move->x,(int)move->y);
29372  if (!res) return(0);
29373  }
29374  }
29375 
29376  return(1);
29377 
29378 } /* end of cuddZddLinearBackward */
Definition: cuddInt.h:469
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
static int cuddZddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:28728
#define CUDD_INVERSE_TRANSFORM_MOVE
Definition: cuddInt.c:28544
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddInt.c:28543
int size
Definition: cuddInt.h:473

◆ cuddZddLinearDown()

static Move * cuddZddLinearDown ( DdManager table,
int  x,
int  xHigh,
Move prevMoves 
)
static

Function********************************************************************

Synopsis [Sifts a variable down and applies the XOR transformation.]

Description [Sifts a variable down. Moves x down until either it reaches the bound (xHigh) or the size of the ZDD heap increases too much. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

SeeAlso []

Definition at line 29262 of file cuddInt.c.

29267 {
29268  Move *moves;
29269  Move *move;
29270  int y;
29271  int size, newsize;
29272  int limitSize;
29273 
29274  moves = prevMoves;
29275  limitSize = table->keysZ;
29276 
29277  y = cuddZddNextHigh(table, x);
29278  while (y <= xHigh) {
29279  size = cuddZddSwapInPlace(table, x, y);
29280  if (size == 0)
29281  goto cuddZddLinearDownOutOfMem;
29282  newsize = cuddZddLinearInPlace(table, x, y);
29283  if (newsize == 0)
29284  goto cuddZddLinearDownOutOfMem;
29285  move = (Move *) cuddDynamicAllocNode(table);
29286  if (move == NULL)
29287  goto cuddZddLinearDownOutOfMem;
29288  move->x = x;
29289  move->y = y;
29290  move->next = moves;
29291  moves = move;
29292  move->flags = CUDD_SWAP_MOVE;
29293  if (newsize > size) {
29294  /* Undo transformation. The transformation we apply is
29295  ** its own inverse. Hence, we just apply the transformation
29296  ** again.
29297  */
29298  newsize = cuddZddLinearInPlace(table,x,y);
29299  if (newsize == 0) goto cuddZddLinearDownOutOfMem;
29300  if (newsize != size) {
29301  (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize);
29302  }
29303  } else {
29304  size = newsize;
29306  }
29307  move->size = size;
29308 
29309  if ((double)size > (double)limitSize * table->maxGrowth)
29310  break;
29311  if (size < limitSize)
29312  limitSize = size;
29313 
29314  x = y;
29315  y = cuddZddNextHigh(table, x);
29316  }
29317  return(moves);
29318 
29319  cuddZddLinearDownOutOfMem:
29320  while (moves != NULL) {
29321  move = moves->next;
29322  cuddDeallocMove(table, moves);
29323  moves = move;
29324  }
29325  return((Move *) CUDD_OUT_OF_MEM);
29326 
29327 } /* end of cuddZddLinearDown */
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:29814
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
FILE * err
Definition: cuddInt.h:424
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define CUDD_SWAP_MOVE
Definition: cuddInt.c:28542
static int cuddZddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:28728
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddInt.c:28543
int size
Definition: cuddInt.h:473

◆ cuddZddLinearInPlace()

static int cuddZddLinearInPlace ( DdManager table,
int  x,
int  y 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Linearly combines two adjacent variables.]

Description [Linearly combines two adjacent variables. It assumes that no dead nodes are present on entry to this procedure. The procedure then guarantees that no dead nodes will be present when it terminates. cuddZddLinearInPlace assumes that x < y. Returns the number of keys in the table if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddZddSwapInPlace cuddLinearInPlace]

Definition at line 28728 of file cuddInt.c.

28732 {
28733  DdNodePtr *xlist, *ylist;
28734  int xindex, yindex;
28735  int xslots, yslots;
28736  int xshift, yshift;
28737  int oldxkeys, oldykeys;
28738  int newxkeys, newykeys;
28739  int i;
28740  int posn;
28741  DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00;
28742  DdNode *newf1, *newf0, *g, *next, *previous;
28743  DdNode *special;
28744 
28745 #ifdef DD_DEBUG
28746  assert(x < y);
28747  assert(cuddZddNextHigh(table,x) == y);
28748  assert(table->subtableZ[x].keys != 0);
28749  assert(table->subtableZ[y].keys != 0);
28750  assert(table->subtableZ[x].dead == 0);
28751  assert(table->subtableZ[y].dead == 0);
28752 #endif
28753 
28755 
28756  /* Get parameters of x subtable. */
28757  xindex = table->invpermZ[x];
28758  xlist = table->subtableZ[x].nodelist;
28759  oldxkeys = table->subtableZ[x].keys;
28760  xslots = table->subtableZ[x].slots;
28761  xshift = table->subtableZ[x].shift;
28762  newxkeys = 0;
28763 
28764  /* Get parameters of y subtable. */
28765  yindex = table->invpermZ[y];
28766  ylist = table->subtableZ[y].nodelist;
28767  oldykeys = table->subtableZ[y].keys;
28768  yslots = table->subtableZ[y].slots;
28769  yshift = table->subtableZ[y].shift;
28770  newykeys = oldykeys;
28771 
28772  /* The nodes in the x layer are put in two chains. The chain
28773  ** pointed by g holds the normal nodes. When re-expressed they stay
28774  ** in the x list. The chain pointed by special holds the elements
28775  ** that will move to the y list.
28776  */
28777  g = special = NULL;
28778  for (i = 0; i < xslots; i++) {
28779  f = xlist[i];
28780  if (f == NULL) continue;
28781  xlist[i] = NULL;
28782  while (f != NULL) {
28783  next = f->next;
28784  f1 = cuddT(f);
28785  /* if (f1->index == yindex) */ cuddSatDec(f1->ref);
28786  f0 = cuddE(f);
28787  /* if (f0->index == yindex) */ cuddSatDec(f0->ref);
28788  if ((int) f1->index == yindex && cuddE(f1) == empty &&
28789  (int) f0->index != yindex) {
28790  f->next = special;
28791  special = f;
28792  } else {
28793  f->next = g;
28794  g = f;
28795  }
28796  f = next;
28797  } /* while there are elements in the collision chain */
28798  } /* for each slot of the x subtable */
28799 
28800  /* Mark y nodes with pointers from above x. We mark them by
28801  ** changing their index to x.
28802  */
28803  for (i = 0; i < yslots; i++) {
28804  f = ylist[i];
28805  while (f != NULL) {
28806  if (f->ref != 0) {
28807  f->index = xindex;
28808  }
28809  f = f->next;
28810  } /* while there are elements in the collision chain */
28811  } /* for each slot of the y subtable */
28812 
28813  /* Move special nodes to the y list. */
28814  f = special;
28815  while (f != NULL) {
28816  next = f->next;
28817  f1 = cuddT(f);
28818  f11 = cuddT(f1);
28819  cuddT(f) = f11;
28820  cuddSatInc(f11->ref);
28821  f0 = cuddE(f);
28822  cuddSatInc(f0->ref);
28823  f->index = yindex;
28824  /* Insert at the beginning of the list so that it will be
28825  ** found first if there is a duplicate. The duplicate will
28826  ** eventually be moved or garbage collected. No node
28827  ** re-expression will add a pointer to it.
28828  */
28829  posn = ddHash(f11, f0, yshift);
28830  f->next = ylist[posn];
28831  ylist[posn] = f;
28832  newykeys++;
28833  f = next;
28834  }
28835 
28836  /* Take care of the remaining x nodes that must be re-expressed.
28837  ** They form a linked list pointed by g.
28838  */
28839  f = g;
28840  while (f != NULL) {
28841 #ifdef DD_COUNT
28842  table->swapSteps++;
28843 #endif
28844  next = f->next;
28845  /* Find f1, f0, f11, f10, f01, f00. */
28846  f1 = cuddT(f);
28847  if ((int) f1->index == yindex || (int) f1->index == xindex) {
28848  f11 = cuddT(f1); f10 = cuddE(f1);
28849  } else {
28850  f11 = empty; f10 = f1;
28851  }
28852  f0 = cuddE(f);
28853  if ((int) f0->index == yindex || (int) f0->index == xindex) {
28854  f01 = cuddT(f0); f00 = cuddE(f0);
28855  } else {
28856  f01 = empty; f00 = f0;
28857  }
28858  /* Create the new T child. */
28859  if (f01 == empty) {
28860  newf1 = f10;
28861  cuddSatInc(newf1->ref);
28862  } else {
28863  /* Check ylist for triple (yindex, f01, f10). */
28864  posn = ddHash(f01, f10, yshift);
28865  /* For each element newf1 in collision list ylist[posn]. */
28866  newf1 = ylist[posn];
28867  /* Search the collision chain skipping the marked nodes. */
28868  while (newf1 != NULL) {
28869  if (cuddT(newf1) == f01 && cuddE(newf1) == f10 &&
28870  (int) newf1->index == yindex) {
28871  cuddSatInc(newf1->ref);
28872  break; /* match */
28873  }
28874  newf1 = newf1->next;
28875  } /* while newf1 */
28876  if (newf1 == NULL) { /* no match */
28877  newf1 = cuddDynamicAllocNode(table);
28878  if (newf1 == NULL)
28879  goto zddSwapOutOfMem;
28880  newf1->index = yindex; newf1->ref = 1;
28881  cuddT(newf1) = f01;
28882  cuddE(newf1) = f10;
28883  /* Insert newf1 in the collision list ylist[pos];
28884  ** increase the ref counts of f01 and f10
28885  */
28886  newykeys++;
28887  newf1->next = ylist[posn];
28888  ylist[posn] = newf1;
28889  cuddSatInc(f01->ref);
28890  cuddSatInc(f10->ref);
28891  }
28892  }
28893  cuddT(f) = newf1;
28894 
28895  /* Do the same for f0. */
28896  /* Create the new E child. */
28897  if (f11 == empty) {
28898  newf0 = f00;
28899  cuddSatInc(newf0->ref);
28900  } else {
28901  /* Check ylist for triple (yindex, f11, f00). */
28902  posn = ddHash(f11, f00, yshift);
28903  /* For each element newf0 in collision list ylist[posn]. */
28904  newf0 = ylist[posn];
28905  while (newf0 != NULL) {
28906  if (cuddT(newf0) == f11 && cuddE(newf0) == f00 &&
28907  (int) newf0->index == yindex) {
28908  cuddSatInc(newf0->ref);
28909  break; /* match */
28910  }
28911  newf0 = newf0->next;
28912  } /* while newf0 */
28913  if (newf0 == NULL) { /* no match */
28914  newf0 = cuddDynamicAllocNode(table);
28915  if (newf0 == NULL)
28916  goto zddSwapOutOfMem;
28917  newf0->index = yindex; newf0->ref = 1;
28918  cuddT(newf0) = f11; cuddE(newf0) = f00;
28919  /* Insert newf0 in the collision list ylist[posn];
28920  ** increase the ref counts of f11 and f00.
28921  */
28922  newykeys++;
28923  newf0->next = ylist[posn];
28924  ylist[posn] = newf0;
28925  cuddSatInc(f11->ref);
28926  cuddSatInc(f00->ref);
28927  }
28928  }
28929  cuddE(f) = newf0;
28930 
28931  /* Re-insert the modified f in xlist.
28932  ** The modified f does not already exists in xlist.
28933  ** (Because of the uniqueness of the cofactors.)
28934  */
28935  posn = ddHash(newf1, newf0, xshift);
28936  newxkeys++;
28937  f->next = xlist[posn];
28938  xlist[posn] = f;
28939  f = next;
28940  } /* while f != NULL */
28941 
28942  /* GC the y layer and move the marked nodes to the x list. */
28943 
28944  /* For each node f in ylist. */
28945  for (i = 0; i < yslots; i++) {
28946  previous = NULL;
28947  f = ylist[i];
28948  while (f != NULL) {
28949  next = f->next;
28950  if (f->ref == 0) {
28951  cuddSatDec(cuddT(f)->ref);
28952  cuddSatDec(cuddE(f)->ref);
28953  cuddDeallocNode(table, f);
28954  newykeys--;
28955  if (previous == NULL)
28956  ylist[i] = next;
28957  else
28958  previous->next = next;
28959  } else if ((int) f->index == xindex) { /* move marked node */
28960  if (previous == NULL)
28961  ylist[i] = next;
28962  else
28963  previous->next = next;
28964  f1 = cuddT(f);
28965  cuddSatDec(f1->ref);
28966  /* Check ylist for triple (yindex, f1, empty). */
28967  posn = ddHash(f1, empty, yshift);
28968  /* For each element newf1 in collision list ylist[posn]. */
28969  newf1 = ylist[posn];
28970  while (newf1 != NULL) {
28971  if (cuddT(newf1) == f1 && cuddE(newf1) == empty &&
28972  (int) newf1->index == yindex) {
28973  cuddSatInc(newf1->ref);
28974  break; /* match */
28975  }
28976  newf1 = newf1->next;
28977  } /* while newf1 */
28978  if (newf1 == NULL) { /* no match */
28979  newf1 = cuddDynamicAllocNode(table);
28980  if (newf1 == NULL)
28981  goto zddSwapOutOfMem;
28982  newf1->index = yindex; newf1->ref = 1;
28983  cuddT(newf1) = f1; cuddE(newf1) = empty;
28984  /* Insert newf1 in the collision list ylist[posn];
28985  ** increase the ref counts of f1 and empty.
28986  */
28987  newykeys++;
28988  newf1->next = ylist[posn];
28989  ylist[posn] = newf1;
28990  if (posn == i && previous == NULL)
28991  previous = newf1;
28992  cuddSatInc(f1->ref);
28993  cuddSatInc(empty->ref);
28994  }
28995  cuddT(f) = newf1;
28996  f0 = cuddE(f);
28997  /* Insert f in x list. */
28998  posn = ddHash(newf1, f0, xshift);
28999  newxkeys++;
29000  newykeys--;
29001  f->next = xlist[posn];
29002  xlist[posn] = f;
29003  } else {
29004  previous = f;
29005  }
29006  f = next;
29007  } /* while f */
29008  } /* for i */
29009 
29010  /* Set the appropriate fields in table. */
29011  table->subtableZ[x].keys = newxkeys;
29012  table->subtableZ[y].keys = newykeys;
29013 
29014  table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys;
29015 
29016  /* Update univ section; univ[x] remains the same. */
29017  table->univ[y] = cuddT(table->univ[x]);
29018 
29019 #if 0
29020  (void) fprintf(table->out,"x = %d y = %d\n", x, y);
29021  (void) Cudd_DebugCheck(table);
29022  (void) Cudd_CheckKeys(table);
29023 #endif
29024 
29025  return (table->keysZ);
29026 
29027  zddSwapOutOfMem:
29028  (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n");
29029 
29030  return (0);
29031 
29032 } /* end of cuddZddLinearInPlace */
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:29814
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
#define ddHash(f, g, s)
Definition: cuddInt.h:696
Definition: cudd.h:264
int * invpermZ
Definition: cuddInt.h:372
#define assert(ex)
Definition: util.h:141
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
static DdNode * empty
Definition: cuddInt.c:28567
FILE * err
Definition: cuddInt.h:424
static int zddTotalNumberLinearTr
Definition: cuddInt.c:28566
unsigned int dead
Definition: cuddInt.h:316
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:267
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:520
int Cudd_CheckKeys(DdManager *table)
Definition: cuddInt.c:5577
DdHalfWord index
Definition: cudd.h:265
unsigned int slots
Definition: cuddInt.h:313
#define cuddE(node)
Definition: cuddInt.h:625
int Cudd_DebugCheck(DdManager *table)
Definition: cuddInt.c:5255
#define cuddSatDec(x)
Definition: cuddInt.h:849
int shift
Definition: cuddInt.h:312
unsigned int keysZ
Definition: cuddInt.h:354
#define cuddSatInc(x)
Definition: cuddInt.h:831
DdSubtable * subtableZ
Definition: cuddInt.h:350
DdNode ** univ
Definition: cuddInt.h:375

◆ cuddZddLinearSifting()

int cuddZddLinearSifting ( DdManager table,
int  lower,
int  upper 
)

AutomaticEnd Function********************************************************************

Synopsis [Implementation of the linear sifting algorithm for ZDDs.]

Description [Implementation of the linear sifting algorithm for ZDDs. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique table.
  2. Sift the variable up and down and applies the XOR transformation, remembering each time the total size of the DD heap.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 28625 of file cuddInt.c.

28629 {
28630  int i;
28631  int *var;
28632  int size;
28633  int x;
28634  int result;
28635 #ifdef DD_STATS
28636  int previousSize;
28637 #endif
28638 
28639  size = table->sizeZ;
28640  empty = table->zero;
28641 
28642  /* Find order in which to sift variables. */
28643  var = NULL;
28644  zdd_entry = ALLOC(int, size);
28645  if (zdd_entry == NULL) {
28646  table->errorCode = CUDD_MEMORY_OUT;
28647  goto cuddZddSiftingOutOfMem;
28648  }
28649  var = ALLOC(int, size);
28650  if (var == NULL) {
28651  table->errorCode = CUDD_MEMORY_OUT;
28652  goto cuddZddSiftingOutOfMem;
28653  }
28654 
28655  for (i = 0; i < size; i++) {
28656  x = table->permZ[i];
28657  zdd_entry[i] = table->subtableZ[x].keys;
28658  var[i] = i;
28659  }
28660 
28661  qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
28662 
28663  /* Now sift. */
28664  for (i = 0; i < ddMin(table->siftMaxVar, size); i++) {
28665  if (zddTotalNumberSwapping >= table->siftMaxSwap)
28666  break;
28667  if (util_cpu_time() - table->startTime > table->timeLimit) {
28668  table->autoDynZ = 0; /* prevent further reordering */
28669  break;
28670  }
28671  x = table->permZ[var[i]];
28672  if (x < lower || x > upper) continue;
28673 #ifdef DD_STATS
28674  previousSize = table->keysZ;
28675 #endif
28676  result = cuddZddLinearAux(table, x, lower, upper);
28677  if (!result)
28678  goto cuddZddSiftingOutOfMem;
28679 #ifdef DD_STATS
28680  if (table->keysZ < (unsigned) previousSize) {
28681  (void) fprintf(table->out,"-");
28682  } else if (table->keysZ > (unsigned) previousSize) {
28683  (void) fprintf(table->out,"+"); /* should never happen */
28684  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]);
28685  } else {
28686  (void) fprintf(table->out,"=");
28687  }
28688  fflush(table->out);
28689 #endif
28690  }
28691 
28692  FREE(var);
28693  FREE(zdd_entry);
28694 
28695  return(1);
28696 
28697  cuddZddSiftingOutOfMem:
28698 
28699  if (zdd_entry != NULL) FREE(zdd_entry);
28700  if (var != NULL) FREE(var);
28701 
28702  return(0);
28703 
28704 } /* end of cuddZddLinearSifting */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:302
unsigned long startTime
Definition: cuddInt.h:426
int * zdd_entry
Definition: cuddInt.c:29545
DdNode * zero
Definition: cuddInt.h:330
static DdNode * empty
Definition: cuddInt.c:28567
int * permZ
Definition: cuddInt.h:370
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddInt.c:29860
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: util.c:34
int zddTotalNumberSwapping
Definition: cuddInt.c:28565
int siftMaxVar
Definition: cuddInt.h:395
int sizeZ
Definition: cuddInt.h:346
static int result
Definition: cuddInt.c:7466
static int cuddZddLinearAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddInt.c:29050
int autoDynZ
Definition: cuddInt.h:401
unsigned int keysZ
Definition: cuddInt.h:354
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddLinearUp()

static Move * cuddZddLinearUp ( DdManager table,
int  y,
int  xLow,
Move prevMoves 
)
static

Function********************************************************************

Synopsis [Sifts a variable up applying the XOR transformation.]

Description [Sifts a variable up applying the XOR transformation. Moves y up until either it reaches the bound (xLow) or the size of the ZDD heap increases too much. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

SeeAlso []

Definition at line 29177 of file cuddInt.c.

29182 {
29183  Move *moves;
29184  Move *move;
29185  int x;
29186  int size, newsize;
29187  int limitSize;
29188 
29189  moves = prevMoves;
29190  limitSize = table->keysZ;
29191 
29192  x = cuddZddNextLow(table, y);
29193  while (x >= xLow) {
29194  size = cuddZddSwapInPlace(table, x, y);
29195  if (size == 0)
29196  goto cuddZddLinearUpOutOfMem;
29197  newsize = cuddZddLinearInPlace(table, x, y);
29198  if (newsize == 0)
29199  goto cuddZddLinearUpOutOfMem;
29200  move = (Move *) cuddDynamicAllocNode(table);
29201  if (move == NULL)
29202  goto cuddZddLinearUpOutOfMem;
29203  move->x = x;
29204  move->y = y;
29205  move->next = moves;
29206  moves = move;
29207  move->flags = CUDD_SWAP_MOVE;
29208  if (newsize > size) {
29209  /* Undo transformation. The transformation we apply is
29210  ** its own inverse. Hence, we just apply the transformation
29211  ** again.
29212  */
29213  newsize = cuddZddLinearInPlace(table,x,y);
29214  if (newsize == 0) goto cuddZddLinearUpOutOfMem;
29215 #ifdef DD_DEBUG
29216  if (newsize != size) {
29217  (void) fprintf(table->err,"Change in size after identity transformation! From %d to %d\n",size,newsize);
29218  }
29219 #endif
29220  } else {
29221  size = newsize;
29223  }
29224  move->size = size;
29225 
29226  if ((double)size > (double)limitSize * table->maxGrowth)
29227  break;
29228  if (size < limitSize)
29229  limitSize = size;
29230 
29231  y = x;
29232  x = cuddZddNextLow(table, y);
29233  }
29234  return(moves);
29235 
29236  cuddZddLinearUpOutOfMem:
29237  while (moves != NULL) {
29238  move = moves->next;
29239  cuddDeallocMove(table, moves);
29240  moves = move;
29241  }
29242  return((Move *) CUDD_OUT_OF_MEM);
29243 
29244 } /* end of cuddZddLinearUp */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
FILE * err
Definition: cuddInt.h:424
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define CUDD_SWAP_MOVE
Definition: cuddInt.c:28542
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddInt.c:29836
static int cuddZddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:28728
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddInt.c:28543
int size
Definition: cuddInt.h:473

◆ cuddZddNextHigh()

int cuddZddNextHigh ( DdManager table,
int  x 
)

Function********************************************************************

Synopsis [Finds the next subtable with a larger index.]

Description [Finds the next subtable with a larger index. Returns the index.]

SideEffects [None]

SeeAlso []

Definition at line 29814 of file cuddInt.c.

29817 {
29818  return(x + 1);
29819 
29820 } /* end of cuddZddNextHigh */

◆ cuddZddNextLow()

int cuddZddNextLow ( DdManager table,
int  x 
)

Function********************************************************************

Synopsis [Finds the next subtable with a smaller index.]

Description [Finds the next subtable with a smaller index. Returns the index.]

SideEffects [None]

SeeAlso []

Definition at line 29836 of file cuddInt.c.

29839 {
29840  return(x - 1);
29841 
29842 } /* end of cuddZddNextLow */

◆ cuddZddProduct()

DdNode* cuddZddProduct ( DdManager dd,
DdNode f,
DdNode g 
)

CFile***********************************************************************

FileName [cuddZddFuncs.c]

PackageName [cudd]

Synopsis [Functions to manipulate covers represented as ZDDs.]

Description [External procedures included in this module:

  • Cudd_zddProduct();
  • Cudd_zddUnateProduct();
  • Cudd_zddWeakDiv();
  • Cudd_zddWeakDivF();
  • Cudd_zddDivide();
  • Cudd_zddDivideF();
  • Cudd_zddComplement();

Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso []

Author [In-Ho Moon]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart AutomaticEnd Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddProduct.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddProduct]

Definition at line 25147 of file cuddInt.c.

25151 {
25152  int v, top_f, top_g;
25153  DdNode *tmp, *term1, *term2, *term3;
25154  DdNode *f0, *f1, *fd, *g0, *g1, *gd;
25155  DdNode *R0, *R1, *Rd, *N0, *N1;
25156  DdNode *r;
25157  DdNode *one = DD_ONE(dd);
25158  DdNode *zero = DD_ZERO(dd);
25159  int flag;
25160  int pv, nv;
25161 
25162  statLine(dd);
25163  if (f == zero || g == zero)
25164  return(zero);
25165  if (f == one)
25166  return(g);
25167  if (g == one)
25168  return(f);
25169 
25170  top_f = dd->permZ[f->index];
25171  top_g = dd->permZ[g->index];
25172 
25173  if (top_f > top_g)
25174  return(cuddZddProduct(dd, g, f));
25175 
25176  /* Check cache */
25177  r = cuddCacheLookup2Zdd(dd, cuddZddProduct, f, g);
25178  if (r)
25179  return(r);
25180 
25181  v = f->index; /* either yi or zi */
25182  flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
25183  if (flag == 1)
25184  return(NULL);
25185  Cudd_Ref(f1);
25186  Cudd_Ref(f0);
25187  Cudd_Ref(fd);
25188  flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd);
25189  if (flag == 1) {
25190  Cudd_RecursiveDerefZdd(dd, f1);
25191  Cudd_RecursiveDerefZdd(dd, f0);
25192  Cudd_RecursiveDerefZdd(dd, fd);
25193  return(NULL);
25194  }
25195  Cudd_Ref(g1);
25196  Cudd_Ref(g0);
25197  Cudd_Ref(gd);
25198  pv = cuddZddGetPosVarIndex(dd, v);
25199  nv = cuddZddGetNegVarIndex(dd, v);
25200 
25201  Rd = cuddZddProduct(dd, fd, gd);
25202  if (Rd == NULL) {
25203  Cudd_RecursiveDerefZdd(dd, f1);
25204  Cudd_RecursiveDerefZdd(dd, f0);
25205  Cudd_RecursiveDerefZdd(dd, fd);
25206  Cudd_RecursiveDerefZdd(dd, g1);
25207  Cudd_RecursiveDerefZdd(dd, g0);
25208  Cudd_RecursiveDerefZdd(dd, gd);
25209  return(NULL);
25210  }
25211  Cudd_Ref(Rd);
25212 
25213  term1 = cuddZddProduct(dd, f0, g0);
25214  if (term1 == NULL) {
25215  Cudd_RecursiveDerefZdd(dd, f1);
25216  Cudd_RecursiveDerefZdd(dd, f0);
25217  Cudd_RecursiveDerefZdd(dd, fd);
25218  Cudd_RecursiveDerefZdd(dd, g1);
25219  Cudd_RecursiveDerefZdd(dd, g0);
25220  Cudd_RecursiveDerefZdd(dd, gd);
25221  Cudd_RecursiveDerefZdd(dd, Rd);
25222  return(NULL);
25223  }
25224  Cudd_Ref(term1);
25225  term2 = cuddZddProduct(dd, f0, gd);
25226  if (term2 == NULL) {
25227  Cudd_RecursiveDerefZdd(dd, f1);
25228  Cudd_RecursiveDerefZdd(dd, f0);
25229  Cudd_RecursiveDerefZdd(dd, fd);
25230  Cudd_RecursiveDerefZdd(dd, g1);
25231  Cudd_RecursiveDerefZdd(dd, g0);
25232  Cudd_RecursiveDerefZdd(dd, gd);
25233  Cudd_RecursiveDerefZdd(dd, Rd);
25234  Cudd_RecursiveDerefZdd(dd, term1);
25235  return(NULL);
25236  }
25237  Cudd_Ref(term2);
25238  term3 = cuddZddProduct(dd, fd, g0);
25239  if (term3 == NULL) {
25240  Cudd_RecursiveDerefZdd(dd, f1);
25241  Cudd_RecursiveDerefZdd(dd, f0);
25242  Cudd_RecursiveDerefZdd(dd, fd);
25243  Cudd_RecursiveDerefZdd(dd, g1);
25244  Cudd_RecursiveDerefZdd(dd, g0);
25245  Cudd_RecursiveDerefZdd(dd, gd);
25246  Cudd_RecursiveDerefZdd(dd, Rd);
25247  Cudd_RecursiveDerefZdd(dd, term1);
25248  Cudd_RecursiveDerefZdd(dd, term2);
25249  return(NULL);
25250  }
25251  Cudd_Ref(term3);
25252  Cudd_RecursiveDerefZdd(dd, f0);
25253  Cudd_RecursiveDerefZdd(dd, g0);
25254  tmp = cuddZddUnion(dd, term1, term2);
25255  if (tmp == NULL) {
25256  Cudd_RecursiveDerefZdd(dd, f1);
25257  Cudd_RecursiveDerefZdd(dd, fd);
25258  Cudd_RecursiveDerefZdd(dd, g1);
25259  Cudd_RecursiveDerefZdd(dd, gd);
25260  Cudd_RecursiveDerefZdd(dd, Rd);
25261  Cudd_RecursiveDerefZdd(dd, term1);
25262  Cudd_RecursiveDerefZdd(dd, term2);
25263  Cudd_RecursiveDerefZdd(dd, term3);
25264  return(NULL);
25265  }
25266  Cudd_Ref(tmp);
25267  Cudd_RecursiveDerefZdd(dd, term1);
25268  Cudd_RecursiveDerefZdd(dd, term2);
25269  R0 = cuddZddUnion(dd, tmp, term3);
25270  if (R0 == NULL) {
25271  Cudd_RecursiveDerefZdd(dd, f1);
25272  Cudd_RecursiveDerefZdd(dd, fd);
25273  Cudd_RecursiveDerefZdd(dd, g1);
25274  Cudd_RecursiveDerefZdd(dd, gd);
25275  Cudd_RecursiveDerefZdd(dd, Rd);
25276  Cudd_RecursiveDerefZdd(dd, term3);
25277  Cudd_RecursiveDerefZdd(dd, tmp);
25278  return(NULL);
25279  }
25280  Cudd_Ref(R0);
25281  Cudd_RecursiveDerefZdd(dd, tmp);
25282  Cudd_RecursiveDerefZdd(dd, term3);
25283  N0 = cuddZddGetNode(dd, nv, R0, Rd); /* nv = zi */
25284  if (N0 == NULL) {
25285  Cudd_RecursiveDerefZdd(dd, f1);
25286  Cudd_RecursiveDerefZdd(dd, fd);
25287  Cudd_RecursiveDerefZdd(dd, g1);
25288  Cudd_RecursiveDerefZdd(dd, gd);
25289  Cudd_RecursiveDerefZdd(dd, Rd);
25290  Cudd_RecursiveDerefZdd(dd, R0);
25291  return(NULL);
25292  }
25293  Cudd_Ref(N0);
25294  Cudd_RecursiveDerefZdd(dd, R0);
25295  Cudd_RecursiveDerefZdd(dd, Rd);
25296 
25297  term1 = cuddZddProduct(dd, f1, g1);
25298  if (term1 == NULL) {
25299  Cudd_RecursiveDerefZdd(dd, f1);
25300  Cudd_RecursiveDerefZdd(dd, fd);
25301  Cudd_RecursiveDerefZdd(dd, g1);
25302  Cudd_RecursiveDerefZdd(dd, gd);
25303  Cudd_RecursiveDerefZdd(dd, N0);
25304  return(NULL);
25305  }
25306  Cudd_Ref(term1);
25307  term2 = cuddZddProduct(dd, f1, gd);
25308  if (term2 == NULL) {
25309  Cudd_RecursiveDerefZdd(dd, f1);
25310  Cudd_RecursiveDerefZdd(dd, fd);
25311  Cudd_RecursiveDerefZdd(dd, g1);
25312  Cudd_RecursiveDerefZdd(dd, gd);
25313  Cudd_RecursiveDerefZdd(dd, N0);
25314  Cudd_RecursiveDerefZdd(dd, term1);
25315  return(NULL);
25316  }
25317  Cudd_Ref(term2);
25318  term3 = cuddZddProduct(dd, fd, g1);
25319  if (term3 == NULL) {
25320  Cudd_RecursiveDerefZdd(dd, f1);
25321  Cudd_RecursiveDerefZdd(dd, fd);
25322  Cudd_RecursiveDerefZdd(dd, g1);
25323  Cudd_RecursiveDerefZdd(dd, gd);
25324  Cudd_RecursiveDerefZdd(dd, N0);
25325  Cudd_RecursiveDerefZdd(dd, term1);
25326  Cudd_RecursiveDerefZdd(dd, term2);
25327  return(NULL);
25328  }
25329  Cudd_Ref(term3);
25330  Cudd_RecursiveDerefZdd(dd, f1);
25331  Cudd_RecursiveDerefZdd(dd, g1);
25332  Cudd_RecursiveDerefZdd(dd, fd);
25333  Cudd_RecursiveDerefZdd(dd, gd);
25334  tmp = cuddZddUnion(dd, term1, term2);
25335  if (tmp == NULL) {
25336  Cudd_RecursiveDerefZdd(dd, N0);
25337  Cudd_RecursiveDerefZdd(dd, term1);
25338  Cudd_RecursiveDerefZdd(dd, term2);
25339  Cudd_RecursiveDerefZdd(dd, term3);
25340  return(NULL);
25341  }
25342  Cudd_Ref(tmp);
25343  Cudd_RecursiveDerefZdd(dd, term1);
25344  Cudd_RecursiveDerefZdd(dd, term2);
25345  R1 = cuddZddUnion(dd, tmp, term3);
25346  if (R1 == NULL) {
25347  Cudd_RecursiveDerefZdd(dd, N0);
25348  Cudd_RecursiveDerefZdd(dd, term3);
25349  Cudd_RecursiveDerefZdd(dd, tmp);
25350  return(NULL);
25351  }
25352  Cudd_Ref(R1);
25353  Cudd_RecursiveDerefZdd(dd, tmp);
25354  Cudd_RecursiveDerefZdd(dd, term3);
25355  N1 = cuddZddGetNode(dd, pv, R1, N0); /* pv = yi */
25356  if (N1 == NULL) {
25357  Cudd_RecursiveDerefZdd(dd, N0);
25358  Cudd_RecursiveDerefZdd(dd, R1);
25359  return(NULL);
25360  }
25361  Cudd_Ref(N1);
25362  Cudd_RecursiveDerefZdd(dd, R1);
25363  Cudd_RecursiveDerefZdd(dd, N0);
25364 
25365  cuddCacheInsert2(dd, cuddZddProduct, f, g, N1);
25366  Cudd_Deref(N1);
25367  return(N1);
25368 
25369 } /* end of cuddZddProduct */
Definition: cudd.h:264
static DdNode * one
Definition: cuddInt.c:16562
int cuddZddGetCofactors3(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)
Definition: cuddInt.c:26127
int cuddZddGetPosVarIndex(DdManager *dd, int index)
Definition: cuddInt.c:26332
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
void Cudd_Ref(DdNode *n)
Definition: cuddInt.c:14002
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddInt.c:31404
DdNode * cuddZddProduct(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:25147
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddInt.c:20408
DdHalfWord index
Definition: cudd.h:265
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void Cudd_Deref(DdNode *node)
Definition: cuddInt.c:14198
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
int cuddZddGetNegVarIndex(DdManager *dd, int index)
Definition: cuddInt.c:26353
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddSifting()

int cuddZddSifting ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [Implementation of Rudell's sifting algorithm.]

Description [Implementation of Rudell's sifting algorithm. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique table.
  2. Sift the variable up and down, remembering each time the total size of the DD heap.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 30268 of file cuddInt.c.

30272 {
30273  int i;
30274  int *var;
30275  int size;
30276  int x;
30277  int result;
30278 #ifdef DD_STATS
30279  int previousSize;
30280 #endif
30281 
30282  size = table->sizeZ;
30283 
30284  /* Find order in which to sift variables. */
30285  var = NULL;
30286  zdd_entry = ALLOC(int, size);
30287  if (zdd_entry == NULL) {
30288  table->errorCode = CUDD_MEMORY_OUT;
30289  goto cuddZddSiftingOutOfMem;
30290  }
30291  var = ALLOC(int, size);
30292  if (var == NULL) {
30293  table->errorCode = CUDD_MEMORY_OUT;
30294  goto cuddZddSiftingOutOfMem;
30295  }
30296 
30297  for (i = 0; i < size; i++) {
30298  x = table->permZ[i];
30299  zdd_entry[i] = table->subtableZ[x].keys;
30300  var[i] = i;
30301  }
30302 
30303  qsort((void *)var, size, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
30304 
30305  /* Now sift. */
30306  for (i = 0; i < ddMin(table->siftMaxVar, size); i++) {
30307  if (zddTotalNumberSwapping >= table->siftMaxSwap)
30308  break;
30309  if (util_cpu_time() - table->startTime > table->timeLimit) {
30310  table->autoDynZ = 0; /* prevent further reordering */
30311  break;
30312  }
30313  x = table->permZ[var[i]];
30314  if (x < lower || x > upper) continue;
30315 #ifdef DD_STATS
30316  previousSize = table->keysZ;
30317 #endif
30318  result = cuddZddSiftingAux(table, x, lower, upper);
30319  if (!result)
30320  goto cuddZddSiftingOutOfMem;
30321 #ifdef DD_STATS
30322  if (table->keysZ < (unsigned) previousSize) {
30323  (void) fprintf(table->out,"-");
30324  } else if (table->keysZ > (unsigned) previousSize) {
30325  (void) fprintf(table->out,"+"); /* should never happen */
30326  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ , var[i]);
30327  } else {
30328  (void) fprintf(table->out,"=");
30329  }
30330  fflush(table->out);
30331 #endif
30332  }
30333 
30334  FREE(var);
30335  FREE(zdd_entry);
30336 
30337  return(1);
30338 
30339  cuddZddSiftingOutOfMem:
30340 
30341  if (zdd_entry != NULL) FREE(zdd_entry);
30342  if (var != NULL) FREE(var);
30343 
30344  return(0);
30345 
30346 } /* end of cuddZddSifting */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:302
unsigned long startTime
Definition: cuddInt.h:426
int * zdd_entry
Definition: cuddInt.c:29545
int * permZ
Definition: cuddInt.h:370
static int cuddZddSiftingAux(DdManager *table, int x, int x_low, int x_high)
Definition: cuddInt.c:30522
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddInt.c:29860
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: util.c:34
int zddTotalNumberSwapping
Definition: cuddInt.c:28565
int siftMaxVar
Definition: cuddInt.h:395
int sizeZ
Definition: cuddInt.h:346
static int result
Definition: cuddInt.c:7466
int autoDynZ
Definition: cuddInt.h:401
unsigned int keysZ
Definition: cuddInt.h:354
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSiftingAux()

static int cuddZddSiftingAux ( DdManager table,
int  x,
int  x_low,
int  x_high 
)
static

Function********************************************************************

Synopsis [Given xLow <= x <= xHigh moves x up and down between the boundaries.]

Description [Given xLow <= x <= xHigh moves x up and down between the boundaries. Finds the best position and does the required changes. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 30522 of file cuddInt.c.

30527 {
30528  Move *move;
30529  Move *moveUp; /* list of up move */
30530  Move *moveDown; /* list of down move */
30531 
30532  int initial_size;
30533  int result;
30534 
30535  initial_size = table->keysZ;
30536 
30537 #ifdef DD_DEBUG
30538  assert(table->subtableZ[x].keys > 0);
30539 #endif
30540 
30541  moveDown = NULL;
30542  moveUp = NULL;
30543 
30544  if (x == x_low) {
30545  moveDown = cuddZddSiftingDown(table, x, x_high, initial_size);
30546  /* after that point x --> x_high */
30547  if (moveDown == NULL)
30548  goto cuddZddSiftingAuxOutOfMem;
30549  result = cuddZddSiftingBackward(table, moveDown,
30550  initial_size);
30551  /* move backward and stop at best position */
30552  if (!result)
30553  goto cuddZddSiftingAuxOutOfMem;
30554 
30555  }
30556  else if (x == x_high) {
30557  moveUp = cuddZddSiftingUp(table, x, x_low, initial_size);
30558  /* after that point x --> x_low */
30559  if (moveUp == NULL)
30560  goto cuddZddSiftingAuxOutOfMem;
30561  result = cuddZddSiftingBackward(table, moveUp, initial_size);
30562  /* move backward and stop at best position */
30563  if (!result)
30564  goto cuddZddSiftingAuxOutOfMem;
30565  }
30566  else if ((x - x_low) > (x_high - x)) {
30567  /* must go down first:shorter */
30568  moveDown = cuddZddSiftingDown(table, x, x_high, initial_size);
30569  /* after that point x --> x_high */
30570  if (moveDown == NULL)
30571  goto cuddZddSiftingAuxOutOfMem;
30572  moveUp = cuddZddSiftingUp(table, moveDown->y, x_low,
30573  initial_size);
30574  if (moveUp == NULL)
30575  goto cuddZddSiftingAuxOutOfMem;
30576  result = cuddZddSiftingBackward(table, moveUp, initial_size);
30577  /* move backward and stop at best position */
30578  if (!result)
30579  goto cuddZddSiftingAuxOutOfMem;
30580  }
30581  else {
30582  moveUp = cuddZddSiftingUp(table, x, x_low, initial_size);
30583  /* after that point x --> x_high */
30584  if (moveUp == NULL)
30585  goto cuddZddSiftingAuxOutOfMem;
30586  moveDown = cuddZddSiftingDown(table, moveUp->x, x_high,
30587  initial_size);
30588  /* then move up */
30589  if (moveDown == NULL)
30590  goto cuddZddSiftingAuxOutOfMem;
30591  result = cuddZddSiftingBackward(table, moveDown,
30592  initial_size);
30593  /* move backward and stop at best position */
30594  if (!result)
30595  goto cuddZddSiftingAuxOutOfMem;
30596  }
30597 
30598  while (moveDown != NULL) {
30599  move = moveDown->next;
30600  cuddDeallocMove(table, moveDown);
30601  moveDown = move;
30602  }
30603  while (moveUp != NULL) {
30604  move = moveUp->next;
30605  cuddDeallocMove(table, moveUp);
30606  moveUp = move;
30607  }
30608 
30609  return(1);
30610 
30611  cuddZddSiftingAuxOutOfMem:
30612  while (moveDown != NULL) {
30613  move = moveDown->next;
30614  cuddDeallocMove(table, moveDown);
30615  moveDown = move;
30616  }
30617  while (moveUp != NULL) {
30618  move = moveUp->next;
30619  cuddDeallocMove(table, moveUp);
30620  moveUp = move;
30621  }
30622 
30623  return(0);
30624 
30625 } /* end of cuddZddSiftingAux */
unsigned int keys
Definition: cuddInt.h:314
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
static Move * cuddZddSiftingUp(DdManager *table, int x, int x_low, int initial_size)
Definition: cuddInt.c:30642
#define assert(ex)
Definition: util.h:141
static Move * cuddZddSiftingDown(DdManager *table, int x, int x_high, int initial_size)
Definition: cuddInt.c:30705
Definition: cuddInt.h:469
static int cuddZddSiftingBackward(DdManager *table, Move *moves, int size)
Definition: cuddInt.c:30769
DdHalfWord x
Definition: cuddInt.h:470
static int result
Definition: cuddInt.c:7466
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSiftingBackward()

static int cuddZddSiftingBackward ( DdManager table,
Move moves,
int  size 
)
static

Function********************************************************************

Synopsis [Given a set of moves, returns the ZDD heap to the position giving the minimum size.]

Description [Given a set of moves, returns the ZDD heap to the position giving the minimum size. In case of ties, returns to the closest position giving the minimum size. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 30769 of file cuddInt.c.

30773 {
30774  int i;
30775  int i_best;
30776  Move *move;
30777  int res;
30778 
30779  /* Find the minimum size among moves. */
30780  i_best = -1;
30781  for (move = moves, i = 0; move != NULL; move = move->next, i++) {
30782  if (move->size < size) {
30783  i_best = i;
30784  size = move->size;
30785  }
30786  }
30787 
30788  for (move = moves, i = 0; move != NULL; move = move->next, i++) {
30789  if (i == i_best)
30790  break;
30791  res = cuddZddSwapInPlace(table, move->x, move->y);
30792  if (!res)
30793  return(0);
30794  if (i_best == -1 && res == size)
30795  break;
30796  }
30797 
30798  return(1);
30799 
30800 } /* end of cuddZddSiftingBackward */
Definition: cuddInt.h:469
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473

◆ cuddZddSiftingDown()

static Move * cuddZddSiftingDown ( DdManager table,
int  x,
int  x_high,
int  initial_size 
)
static

Function********************************************************************

Synopsis [Sifts a variable down.]

Description [Sifts a variable down. Moves x down until either it reaches the bound (x_high) or the size of the ZDD heap increases too much. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

SeeAlso []

Definition at line 30705 of file cuddInt.c.

30710 {
30711  Move *moves;
30712  Move *move;
30713  int y;
30714  int size;
30715  int limit_size = initial_size;
30716 
30717  moves = NULL;
30718  y = cuddZddNextHigh(table, x);
30719  while (y <= x_high) {
30720  size = cuddZddSwapInPlace(table, x, y);
30721  if (size == 0)
30722  goto cuddZddSiftingDownOutOfMem;
30723  move = (Move *)cuddDynamicAllocNode(table);
30724  if (move == NULL)
30725  goto cuddZddSiftingDownOutOfMem;
30726  move->x = x;
30727  move->y = y;
30728  move->size = size;
30729  move->next = moves;
30730  moves = move;
30731 
30732  if ((double)size > (double)limit_size * table->maxGrowth)
30733  break;
30734  if (size < limit_size)
30735  limit_size = size;
30736 
30737  x = y;
30738  y = cuddZddNextHigh(table, x);
30739  }
30740  return(moves);
30741 
30742  cuddZddSiftingDownOutOfMem:
30743  while (moves != NULL) {
30744  move = moves->next;
30745  cuddDeallocMove(table, moves);
30746  moves = move;
30747  }
30748  return(NULL);
30749 
30750 } /* end of cuddZddSiftingDown */
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:29814
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473

◆ cuddZddSiftingUp()

static Move * cuddZddSiftingUp ( DdManager table,
int  x,
int  x_low,
int  initial_size 
)
static

Function********************************************************************

Synopsis [Sifts a variable up.]

Description [Sifts a variable up. Moves y up until either it reaches the bound (x_low) or the size of the ZDD heap increases too much. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

SeeAlso []

Definition at line 30642 of file cuddInt.c.

30647 {
30648  Move *moves;
30649  Move *move;
30650  int y;
30651  int size;
30652  int limit_size = initial_size;
30653 
30654  moves = NULL;
30655  y = cuddZddNextLow(table, x);
30656  while (y >= x_low) {
30657  size = cuddZddSwapInPlace(table, y, x);
30658  if (size == 0)
30659  goto cuddZddSiftingUpOutOfMem;
30660  move = (Move *)cuddDynamicAllocNode(table);
30661  if (move == NULL)
30662  goto cuddZddSiftingUpOutOfMem;
30663  move->x = y;
30664  move->y = x;
30665  move->size = size;
30666  move->next = moves;
30667  moves = move;
30668 
30669  if ((double)size > (double)limit_size * table->maxGrowth)
30670  break;
30671  if (size < limit_size)
30672  limit_size = size;
30673 
30674  x = y;
30675  y = cuddZddNextLow(table, x);
30676  }
30677  return(moves);
30678 
30679  cuddZddSiftingUpOutOfMem:
30680  while (moves != NULL) {
30681  move = moves->next;
30682  cuddDeallocMove(table, moves);
30683  moves = move;
30684  }
30685  return(NULL);
30686 
30687 } /* end of cuddZddSiftingUp */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddInt.c:29836
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473

◆ cuddZddSubset0()

DdNode* cuddZddSubset0 ( DdManager dd,
DdNode P,
int  var 
)

Function********************************************************************

Synopsis [Computes the negative cofactor of a ZDD w.r.t. a variable.]

Description [Computes the negative cofactor of a ZDD w.r.t. a variable. In terms of combinations, the result is the set of all combinations in which the variable is negated. Returns a pointer to the result if successful; NULL otherwise. cuddZddSubset0 performs the same function as Cudd_zddSubset0, but does not restart if reordering has taken place. Therefore it can be called from within a recursive procedure.]

SideEffects [None]

SeeAlso [cuddZddSubset1 Cudd_zddSubset0]

Definition at line 31774 of file cuddInt.c.

31778 {
31779  DdNode *zvar, *r;
31780  DdNode *base, *empty;
31781 
31782  base = DD_ONE(dd);
31783  empty = DD_ZERO(dd);
31784 
31785  zvar = cuddUniqueInterZdd(dd, var, base, empty);
31786  if (zvar == NULL) {
31787  return(NULL);
31788  } else {
31789  cuddRef(zvar);
31790  r = zdd_subset0_aux(dd, P, zvar);
31791  if (r == NULL) {
31792  Cudd_RecursiveDerefZdd(dd, zvar);
31793  return(NULL);
31794  }
31795  cuddRef(r);
31796  Cudd_RecursiveDerefZdd(dd, zvar);
31797  }
31798 
31799  cuddDeref(r);
31800  return(r);
31801 
31802 } /* end of cuddZddSubset0 */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
static DdNode * empty
Definition: cuddInt.c:28567
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20730
static DdNode * zdd_subset0_aux(DdManager *zdd, DdNode *P, DdNode *zvar)
Definition: cuddInt.c:31891
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddSubset1()

DdNode* cuddZddSubset1 ( DdManager dd,
DdNode P,
int  var 
)

Function********************************************************************

Synopsis [Computes the positive cofactor of a ZDD w.r.t. a variable.]

Description [Computes the positive cofactor of a ZDD w.r.t. a variable. In terms of combinations, the result is the set of all combinations in which the variable is asserted. Returns a pointer to the result if successful; NULL otherwise. cuddZddSubset1 performs the same function as Cudd_zddSubset1, but does not restart if reordering has taken place. Therefore it can be called from within a recursive procedure.]

SideEffects [None]

SeeAlso [cuddZddSubset0 Cudd_zddSubset1]

Definition at line 31725 of file cuddInt.c.

31729 {
31730  DdNode *zvar, *r;
31731  DdNode *base, *empty;
31732 
31733  base = DD_ONE(dd);
31734  empty = DD_ZERO(dd);
31735 
31736  zvar = cuddUniqueInterZdd(dd, var, base, empty);
31737  if (zvar == NULL) {
31738  return(NULL);
31739  } else {
31740  cuddRef(zvar);
31741  r = zdd_subset1_aux(dd, P, zvar);
31742  if (r == NULL) {
31743  Cudd_RecursiveDerefZdd(dd, zvar);
31744  return(NULL);
31745  }
31746  cuddRef(r);
31747  Cudd_RecursiveDerefZdd(dd, zvar);
31748  }
31749 
31750  cuddDeref(r);
31751  return(r);
31752 
31753 } /* end of cuddZddSubset1 */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
static DdNode * empty
Definition: cuddInt.c:28567
DdNode * cuddUniqueInterZdd(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20730
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
static DdNode * zdd_subset1_aux(DdManager *zdd, DdNode *P, DdNode *zvar)
Definition: cuddInt.c:31822
#define DD_ONE(dd)
Definition: cuddInt.h:864
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddSwapInPlace()

int cuddZddSwapInPlace ( DdManager table,
int  x,
int  y 
)

Function********************************************************************

Synopsis [Swaps two adjacent variables.]

Description [Swaps two adjacent variables. It assumes that no dead nodes are present on entry to this procedure. The procedure then guarantees that no dead nodes will be present when it terminates. cuddZddSwapInPlace assumes that x < y. Returns the number of keys in the table if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 29885 of file cuddInt.c.

29889 {
29890  DdNodePtr *xlist, *ylist;
29891  int xindex, yindex;
29892  int xslots, yslots;
29893  int xshift, yshift;
29894  int oldxkeys, oldykeys;
29895  int newxkeys, newykeys;
29896  int i;
29897  int posn;
29898  DdNode *f, *f1, *f0, *f11, *f10, *f01, *f00;
29899  DdNode *newf1, *newf0, *next;
29900  DdNodePtr g, *lastP, *previousP;
29901 
29902 #ifdef DD_DEBUG
29903  assert(x < y);
29904  assert(cuddZddNextHigh(table,x) == y);
29905  assert(table->subtableZ[x].keys != 0);
29906  assert(table->subtableZ[y].keys != 0);
29907  assert(table->subtableZ[x].dead == 0);
29908  assert(table->subtableZ[y].dead == 0);
29909 #endif
29910 
29912 
29913  /* Get parameters of x subtable. */
29914  xindex = table->invpermZ[x];
29915  xlist = table->subtableZ[x].nodelist;
29916  oldxkeys = table->subtableZ[x].keys;
29917  xslots = table->subtableZ[x].slots;
29918  xshift = table->subtableZ[x].shift;
29919  newxkeys = 0;
29920 
29921  yindex = table->invpermZ[y];
29922  ylist = table->subtableZ[y].nodelist;
29923  oldykeys = table->subtableZ[y].keys;
29924  yslots = table->subtableZ[y].slots;
29925  yshift = table->subtableZ[y].shift;
29926  newykeys = oldykeys;
29927 
29928  /* The nodes in the x layer that don't depend on y directly
29929  ** will stay there; the others are put in a chain.
29930  ** The chain is handled as a FIFO; g points to the beginning and
29931  ** last points to the end.
29932  */
29933 
29934  g = NULL;
29935  lastP = &g;
29936  for (i = 0; i < xslots; i++) {
29937  previousP = &(xlist[i]);
29938  f = *previousP;
29939  while (f != NULL) {
29940  next = f->next;
29941  f1 = cuddT(f); f0 = cuddE(f);
29942  if ((f1->index != (DdHalfWord) yindex) &&
29943  (f0->index != (DdHalfWord) yindex)) { /* stays */
29944  newxkeys++;
29945  *previousP = f;
29946  previousP = &(f->next);
29947  } else {
29948  f->index = yindex;
29949  *lastP = f;
29950  lastP = &(f->next);
29951  }
29952  f = next;
29953  } /* while there are elements in the collision chain */
29954  *previousP = NULL;
29955  } /* for each slot of the x subtable */
29956  *lastP = NULL;
29957 
29958 
29959 #ifdef DD_COUNT
29960  table->swapSteps += oldxkeys - newxkeys;
29961 #endif
29962  /* Take care of the x nodes that must be re-expressed.
29963  ** They form a linked list pointed by g. Their index has been
29964  ** changed to yindex already.
29965  */
29966  f = g;
29967  while (f != NULL) {
29968  next = f->next;
29969  /* Find f1, f0, f11, f10, f01, f00. */
29970  f1 = cuddT(f);
29971  if ((int) f1->index == yindex) {
29972  f11 = cuddT(f1); f10 = cuddE(f1);
29973  } else {
29974  f11 = empty; f10 = f1;
29975  }
29976  f0 = cuddE(f);
29977  if ((int) f0->index == yindex) {
29978  f01 = cuddT(f0); f00 = cuddE(f0);
29979  } else {
29980  f01 = empty; f00 = f0;
29981  }
29982 
29983  /* Decrease ref count of f1. */
29984  cuddSatDec(f1->ref);
29985  /* Create the new T child. */
29986  if (f11 == empty) {
29987  if (f01 != empty) {
29988  newf1 = f01;
29989  cuddSatInc(newf1->ref);
29990  }
29991  /* else case was already handled when finding nodes
29992  ** with both children below level y
29993  */
29994  } else {
29995  /* Check xlist for triple (xindex, f11, f01). */
29996  posn = ddHash(f11, f01, xshift);
29997  /* For each element newf1 in collision list xlist[posn]. */
29998  newf1 = xlist[posn];
29999  while (newf1 != NULL) {
30000  if (cuddT(newf1) == f11 && cuddE(newf1) == f01) {
30001  cuddSatInc(newf1->ref);
30002  break; /* match */
30003  }
30004  newf1 = newf1->next;
30005  } /* while newf1 */
30006  if (newf1 == NULL) { /* no match */
30007  newf1 = cuddDynamicAllocNode(table);
30008  if (newf1 == NULL)
30009  goto zddSwapOutOfMem;
30010  newf1->index = xindex; newf1->ref = 1;
30011  cuddT(newf1) = f11;
30012  cuddE(newf1) = f01;
30013  /* Insert newf1 in the collision list xlist[pos];
30014  ** increase the ref counts of f11 and f01
30015  */
30016  newxkeys++;
30017  newf1->next = xlist[posn];
30018  xlist[posn] = newf1;
30019  cuddSatInc(f11->ref);
30020  cuddSatInc(f01->ref);
30021  }
30022  }
30023  cuddT(f) = newf1;
30024 
30025  /* Do the same for f0. */
30026  /* Decrease ref count of f0. */
30027  cuddSatDec(f0->ref);
30028  /* Create the new E child. */
30029  if (f10 == empty) {
30030  newf0 = f00;
30031  cuddSatInc(newf0->ref);
30032  } else {
30033  /* Check xlist for triple (xindex, f10, f00). */
30034  posn = ddHash(f10, f00, xshift);
30035  /* For each element newf0 in collision list xlist[posn]. */
30036  newf0 = xlist[posn];
30037  while (newf0 != NULL) {
30038  if (cuddT(newf0) == f10 && cuddE(newf0) == f00) {
30039  cuddSatInc(newf0->ref);
30040  break; /* match */
30041  }
30042  newf0 = newf0->next;
30043  } /* while newf0 */
30044  if (newf0 == NULL) { /* no match */
30045  newf0 = cuddDynamicAllocNode(table);
30046  if (newf0 == NULL)
30047  goto zddSwapOutOfMem;
30048  newf0->index = xindex; newf0->ref = 1;
30049  cuddT(newf0) = f10; cuddE(newf0) = f00;
30050  /* Insert newf0 in the collision list xlist[posn];
30051  ** increase the ref counts of f10 and f00.
30052  */
30053  newxkeys++;
30054  newf0->next = xlist[posn];
30055  xlist[posn] = newf0;
30056  cuddSatInc(f10->ref);
30057  cuddSatInc(f00->ref);
30058  }
30059  }
30060  cuddE(f) = newf0;
30061 
30062  /* Insert the modified f in ylist.
30063  ** The modified f does not already exists in ylist.
30064  ** (Because of the uniqueness of the cofactors.)
30065  */
30066  posn = ddHash(newf1, newf0, yshift);
30067  newykeys++;
30068  f->next = ylist[posn];
30069  ylist[posn] = f;
30070  f = next;
30071  } /* while f != NULL */
30072 
30073  /* GC the y layer. */
30074 
30075  /* For each node f in ylist. */
30076  for (i = 0; i < yslots; i++) {
30077  previousP = &(ylist[i]);
30078  f = *previousP;
30079  while (f != NULL) {
30080  next = f->next;
30081  if (f->ref == 0) {
30082  cuddSatDec(cuddT(f)->ref);
30083  cuddSatDec(cuddE(f)->ref);
30084  cuddDeallocNode(table, f);
30085  newykeys--;
30086  } else {
30087  *previousP = f;
30088  previousP = &(f->next);
30089  }
30090  f = next;
30091  } /* while f */
30092  *previousP = NULL;
30093  } /* for i */
30094 
30095  /* Set the appropriate fields in table. */
30096  table->subtableZ[x].nodelist = ylist;
30097  table->subtableZ[x].slots = yslots;
30098  table->subtableZ[x].shift = yshift;
30099  table->subtableZ[x].keys = newykeys;
30100  table->subtableZ[x].maxKeys = yslots * DD_MAX_SUBTABLE_DENSITY;
30101 
30102  table->subtableZ[y].nodelist = xlist;
30103  table->subtableZ[y].slots = xslots;
30104  table->subtableZ[y].shift = xshift;
30105  table->subtableZ[y].keys = newxkeys;
30106  table->subtableZ[y].maxKeys = xslots * DD_MAX_SUBTABLE_DENSITY;
30107 
30108  table->permZ[xindex] = y; table->permZ[yindex] = x;
30109  table->invpermZ[x] = yindex; table->invpermZ[y] = xindex;
30110 
30111  table->keysZ += newxkeys + newykeys - oldxkeys - oldykeys;
30112 
30113  /* Update univ section; univ[x] remains the same. */
30114  table->univ[y] = cuddT(table->univ[x]);
30115 
30116  return (table->keysZ);
30117 
30118  zddSwapOutOfMem:
30119  (void) fprintf(table->err, "Error: cuddZddSwapInPlace out of memory\n");
30120 
30121  return (0);
30122 
30123 } /* end of cuddZddSwapInPlace */
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:29814
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
unsigned short DdHalfWord
Definition: cudd.h:253
#define ddHash(f, g, s)
Definition: cuddInt.h:696
Definition: cudd.h:264
int * invpermZ
Definition: cuddInt.h:372
#define assert(ex)
Definition: util.h:141
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
static DdNode * empty
Definition: cuddInt.c:28567
FILE * err
Definition: cuddInt.h:424
int * permZ
Definition: cuddInt.h:370
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:267
unsigned int maxKeys
Definition: cuddInt.h:315
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:520
int zddTotalNumberSwapping
Definition: cuddInt.c:28565
DdHalfWord index
Definition: cudd.h:265
unsigned int slots
Definition: cuddInt.h:313
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
int shift
Definition: cuddInt.h:312
unsigned int keysZ
Definition: cuddInt.h:354
#define cuddSatInc(x)
Definition: cuddInt.h:831
DdSubtable * subtableZ
Definition: cuddInt.h:350
DdNode ** univ
Definition: cuddInt.h:375

◆ cuddZddSwapping()

int cuddZddSwapping ( DdManager table,
int  lower,
int  upper,
Cudd_ReorderingType  heuristic 
)

Function********************************************************************

Synopsis [Reorders variables by a sequence of (non-adjacent) swaps.]

Description [Implementation of Plessier's algorithm that reorders variables by a sequence of (non-adjacent) swaps.

  1. Select two variables (RANDOM or HEURISTIC).
  2. Permute these variables.
  3. If the nodes have decreased accept the permutation.
  4. Otherwise reconstruct the original heap.
  5. Loop.

Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 30147 of file cuddInt.c.

30152 {
30153  int i, j;
30154  int max, keys;
30155  int nvars;
30156  int x, y;
30157  int iterate;
30158  int previousSize;
30159  Move *moves, *move;
30160  int pivot;
30161  int modulo;
30162  int result;
30163 
30164 #ifdef DD_DEBUG
30165  /* Sanity check */
30166  assert(lower >= 0 && upper < table->sizeZ && lower <= upper);
30167 #endif
30168 
30169  nvars = upper - lower + 1;
30170  iterate = nvars;
30171 
30172  for (i = 0; i < iterate; i++) {
30173  if (heuristic == CUDD_REORDER_RANDOM_PIVOT) {
30174  /* Find pivot <= id with maximum keys. */
30175  for (max = -1, j = lower; j <= upper; j++) {
30176  if ((keys = table->subtableZ[j].keys) > max) {
30177  max = keys;
30178  pivot = j;
30179  }
30180  }
30181 
30182  modulo = upper - pivot;
30183  if (modulo == 0) {
30184  y = pivot; /* y = nvars-1 */
30185  } else {
30186  /* y = random # from {pivot+1 .. nvars-1} */
30187  y = pivot + 1 + (int) (Cudd_Random() % modulo);
30188  }
30189 
30190  modulo = pivot - lower - 1;
30191  if (modulo < 1) { /* if pivot = 1 or 0 */
30192  x = lower;
30193  } else {
30194  do { /* x = random # from {0 .. pivot-2} */
30195  x = (int) Cudd_Random() % modulo;
30196  } while (x == y);
30197  /* Is this condition really needed, since x and y
30198  are in regions separated by pivot? */
30199  }
30200  } else {
30201  x = (int) (Cudd_Random() % nvars) + lower;
30202  do {
30203  y = (int) (Cudd_Random() % nvars) + lower;
30204  } while (x == y);
30205  }
30206 
30207  previousSize = table->keysZ;
30208  moves = zddSwapAny(table, x, y);
30209  if (moves == NULL)
30210  goto cuddZddSwappingOutOfMem;
30211 
30212  result = cuddZddSiftingBackward(table, moves, previousSize);
30213  if (!result)
30214  goto cuddZddSwappingOutOfMem;
30215 
30216  while (moves != NULL) {
30217  move = moves->next;
30218  cuddDeallocMove(table, moves);
30219  moves = move;
30220  }
30221 #ifdef DD_STATS
30222  if (table->keysZ < (unsigned) previousSize) {
30223  (void) fprintf(table->out,"-");
30224  } else if (table->keysZ > (unsigned) previousSize) {
30225  (void) fprintf(table->out,"+"); /* should never happen */
30226  } else {
30227  (void) fprintf(table->out,"=");
30228  }
30229  fflush(table->out);
30230 #endif
30231  }
30232 
30233  return(1);
30234 
30235  cuddZddSwappingOutOfMem:
30236  while (moves != NULL) {
30237  move = moves->next;
30238  cuddDeallocMove(table, moves);
30239  moves = move;
30240  }
30241  return(0);
30242 
30243 } /* end of cuddZddSwapping */
unsigned int keys
Definition: cuddInt.h:314
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
static Move * zddSwapAny(DdManager *table, int x, int y)
Definition: cuddInt.c:30366
static int cuddZddSiftingBackward(DdManager *table, Move *moves, int size)
Definition: cuddInt.c:30769
FILE * out
Definition: cuddInt.h:423
static int result
Definition: cuddInt.c:7466
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
long Cudd_Random(void)
Definition: cuddInt.c:22881
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSymmCheck()

int cuddZddSymmCheck ( DdManager table,
int  x,
int  y 
)

AutomaticEnd Function********************************************************************

Synopsis [Checks for symmetry of x and y.]

Description [Checks for symmetry of x and y. Ignores projection functions, unless they are isolated. Returns 1 in case of symmetry; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 32127 of file cuddInt.c.

32131 {
32132  int i;
32133  DdNode *f, *f0, *f1, *f01, *f00, *f11, *f10;
32134  int yindex;
32135  int xsymmy = 1;
32136  int xsymmyp = 1;
32137  int arccount = 0;
32138  int TotalRefCount = 0;
32139  int symm_found;
32140 
32141  empty = table->zero;
32142 
32143  yindex = table->invpermZ[y];
32144  for (i = table->subtableZ[x].slots - 1; i >= 0; i--) {
32145  f = table->subtableZ[x].nodelist[i];
32146  while (f != NULL) {
32147  /* Find f1, f0, f11, f10, f01, f00 */
32148  f1 = cuddT(f);
32149  f0 = cuddE(f);
32150  if ((int) f1->index == yindex) {
32151  f11 = cuddT(f1);
32152  f10 = cuddE(f1);
32153  if (f10 != empty)
32154  arccount++;
32155  } else {
32156  if ((int) f0->index != yindex) {
32157  return(0); /* f bypasses layer y */
32158  }
32159  f11 = empty;
32160  f10 = f1;
32161  }
32162  if ((int) f0->index == yindex) {
32163  f01 = cuddT(f0);
32164  f00 = cuddE(f0);
32165  if (f00 != empty)
32166  arccount++;
32167  } else {
32168  f01 = empty;
32169  f00 = f0;
32170  }
32171  if (f01 != f10)
32172  xsymmy = 0;
32173  if (f11 != f00)
32174  xsymmyp = 0;
32175  if ((xsymmy == 0) && (xsymmyp == 0))
32176  return(0);
32177 
32178  f = f->next;
32179  } /* for each element of the collision list */
32180  } /* for each slot of the subtable */
32181 
32182  /* Calculate the total reference counts of y
32183  ** whose else arc is not empty.
32184  */
32185  for (i = table->subtableZ[y].slots - 1; i >= 0; i--) {
32186  f = table->subtableZ[y].nodelist[i];
32187  while (f != NIL(DdNode)) {
32188  if (cuddE(f) != empty)
32189  TotalRefCount += f->ref;
32190  f = f->next;
32191  }
32192  }
32193 
32194  symm_found = (arccount == TotalRefCount);
32195 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
32196  if (symm_found) {
32197  int xindex = table->invpermZ[x];
32198  (void) fprintf(table->out,
32199  "Found symmetry! x =%d\ty = %d\tPos(%d,%d)\n",
32200  xindex,yindex,x,y);
32201  }
32202 #endif
32203 
32204  return(symm_found);
32205 
32206 } /* end cuddZddSymmCheck */
DdHalfWord ref
Definition: cudd.h:266
Definition: cudd.h:264
int * invpermZ
Definition: cuddInt.h:372
DdNode * zero
Definition: cuddInt.h:330
static DdNode * empty
Definition: cuddInt.c:28567
#define NIL(type)
Definition: util.h:44
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:267
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
unsigned int slots
Definition: cuddInt.h:313
#define cuddE(node)
Definition: cuddInt.h:625
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSymmSifting()

int cuddZddSymmSifting ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [Symmetric sifting algorithm for ZDDs.]

Description [Symmetric sifting algorithm. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique subtable.
  2. Sift the variable up and down, remembering each time the total size of the ZDD heap and grouping variables that are symmetric.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.

Returns 1 plus the number of symmetric variables if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddZddSymmSiftingConv]

Definition at line 32232 of file cuddInt.c.

32236 {
32237  int i;
32238  int *var;
32239  int nvars;
32240  int x;
32241  int result;
32242  int symvars;
32243  int symgroups;
32244  int iteration;
32245 #ifdef DD_STATS
32246  int previousSize;
32247 #endif
32248 
32249  nvars = table->sizeZ;
32250 
32251  /* Find order in which to sift variables. */
32252  var = NULL;
32253  zdd_entry = ALLOC(int, nvars);
32254  if (zdd_entry == NULL) {
32255  table->errorCode = CUDD_MEMORY_OUT;
32256  goto cuddZddSymmSiftingOutOfMem;
32257  }
32258  var = ALLOC(int, nvars);
32259  if (var == NULL) {
32260  table->errorCode = CUDD_MEMORY_OUT;
32261  goto cuddZddSymmSiftingOutOfMem;
32262  }
32263 
32264  for (i = 0; i < nvars; i++) {
32265  x = table->permZ[i];
32266  zdd_entry[i] = table->subtableZ[x].keys;
32267  var[i] = i;
32268  }
32269 
32270  qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
32271 
32272  /* Initialize the symmetry of each subtable to itself. */
32273  for (i = lower; i <= upper; i++)
32274  table->subtableZ[i].next = i;
32275 
32276  iteration = ddMin(table->siftMaxVar, nvars);
32277  for (i = 0; i < iteration; i++) {
32278  if (zddTotalNumberSwapping >= table->siftMaxSwap)
32279  break;
32280  if (util_cpu_time() - table->startTime > table->timeLimit) {
32281  table->autoDynZ = 0; /* prevent further reordering */
32282  break;
32283  }
32284  x = table->permZ[var[i]];
32285 #ifdef DD_STATS
32286  previousSize = table->keysZ;
32287 #endif
32288  if (x < lower || x > upper) continue;
32289  if (table->subtableZ[x].next == (unsigned) x) {
32290  result = cuddZddSymmSiftingAux(table, x, lower, upper);
32291  if (!result)
32292  goto cuddZddSymmSiftingOutOfMem;
32293 #ifdef DD_STATS
32294  if (table->keysZ < (unsigned) previousSize) {
32295  (void) fprintf(table->out,"-");
32296  } else if (table->keysZ > (unsigned) previousSize) {
32297  (void) fprintf(table->out,"+");
32298 #ifdef DD_VERBOSE
32299  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]);
32300 #endif
32301  } else {
32302  (void) fprintf(table->out,"=");
32303  }
32304  fflush(table->out);
32305 #endif
32306  }
32307  }
32308 
32309  FREE(var);
32310  FREE(zdd_entry);
32311 
32312  cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups);
32313 
32314 #ifdef DD_STATS
32315  (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",symvars);
32316  (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",symgroups);
32317 #endif
32318 
32319  return(1+symvars);
32320 
32321  cuddZddSymmSiftingOutOfMem:
32322 
32323  if (zdd_entry != NULL)
32324  FREE(zdd_entry);
32325  if (var != NULL)
32326  FREE(var);
32327 
32328  return(0);
32329 
32330 } /* end of cuddZddSymmSifting */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:302
unsigned long startTime
Definition: cuddInt.h:426
int * zdd_entry
Definition: cuddInt.c:29545
int * permZ
Definition: cuddInt.h:370
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static void cuddZddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
Definition: cuddInt.c:33613
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddInt.c:29860
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: util.c:34
int zddTotalNumberSwapping
Definition: cuddInt.c:28565
int siftMaxVar
Definition: cuddInt.h:395
int sizeZ
Definition: cuddInt.h:346
static int result
Definition: cuddInt.c:7466
unsigned int next
Definition: cuddInt.h:317
int autoDynZ
Definition: cuddInt.h:401
static int cuddZddSymmSiftingAux(DdManager *table, int x, int x_low, int x_high)
Definition: cuddInt.c:32543
unsigned int keysZ
Definition: cuddInt.h:354
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSymmSifting_down()

static Move * cuddZddSymmSifting_down ( DdManager table,
int  x,
int  x_high,
int  initial_size 
)
static

Function********************************************************************

Synopsis [Moves x down until either it reaches the bound (x_high) or the size of the ZDD heap increases too much.]

Description [Moves x down until either it reaches the bound (x_high) or the size of the ZDD heap increases too much. Assumes that x is the bottom of a symmetry group. Checks x for symmetry to the adjacent variables. If symmetry is found, the symmetry group of x is merged with the symmetry group of the other variable. Returns the set of moves in case of success; ZDD_MV_OOM if memory is full.]

SideEffects [None]

SeeAlso []

Definition at line 33280 of file cuddInt.c.

33285 {
33286  Move *moves;
33287  Move *move;
33288  int y;
33289  int size;
33290  int limit_size = initial_size;
33291  int i, gxtop, gybot;
33292 
33293  moves = NULL;
33294  y = cuddZddNextHigh(table, x);
33295  while (y <= x_high) {
33296  gybot = table->subtableZ[y].next;
33297  while (table->subtableZ[gybot].next != (unsigned) y)
33298  gybot = table->subtableZ[gybot].next;
33299  if (cuddZddSymmCheck(table, x, y)) {
33300  /* Symmetry found, attach symm groups */
33301  gxtop = table->subtableZ[x].next;
33302  table->subtableZ[x].next = y;
33303  i = table->subtableZ[y].next;
33304  while (table->subtableZ[i].next != (unsigned) y)
33305  i = table->subtableZ[i].next;
33306  table->subtableZ[i].next = gxtop;
33307  }
33308  else if ((table->subtableZ[x].next == (unsigned) x) &&
33309  (table->subtableZ[y].next == (unsigned) y)) {
33310  /* x and y have self symmetry */
33311  size = cuddZddSwapInPlace(table, x, y);
33312  if (size == 0)
33313  goto cuddZddSymmSifting_downOutOfMem;
33314  move = (Move *)cuddDynamicAllocNode(table);
33315  if (move == NULL)
33316  goto cuddZddSymmSifting_downOutOfMem;
33317  move->x = x;
33318  move->y = y;
33319  move->size = size;
33320  move->next = moves;
33321  moves = move;
33322  if ((double)size >
33323  (double)limit_size * table->maxGrowth)
33324  return(moves);
33325  if (size < limit_size)
33326  limit_size = size;
33327  x = y;
33328  y = cuddZddNextHigh(table, x);
33329  }
33330  else { /* Group move */
33331  size = zdd_group_move(table, x, y, &moves);
33332  if ((double)size >
33333  (double)limit_size * table->maxGrowth)
33334  return(moves);
33335  if (size < limit_size)
33336  limit_size = size;
33337  }
33338  x = gybot;
33339  y = cuddZddNextHigh(table, x);
33340  }
33341 
33342  return(moves);
33343 
33344  cuddZddSymmSifting_downOutOfMem:
33345  while (moves != NULL) {
33346  move = moves->next;
33347  cuddDeallocMove(table, moves);
33348  moves = move;
33349  }
33350  return(ZDD_MV_OOM);
33351 
33352 } /* end of cuddZddSymmSifting_down */
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:29814
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
static int zdd_group_move(DdManager *table, int x, int y, Move **moves)
Definition: cuddInt.c:33423
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
DdHalfWord x
Definition: cuddInt.h:470
#define ZDD_MV_OOM
Definition: cuddInt.c:32055
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
int cuddZddSymmCheck(DdManager *table, int x, int y)
Definition: cuddInt.c:32127
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSymmSifting_up()

static Move * cuddZddSymmSifting_up ( DdManager table,
int  x,
int  x_low,
int  initial_size 
)
static

Function********************************************************************

Synopsis [Moves x up until either it reaches the bound (x_low) or the size of the ZDD heap increases too much.]

Description [Moves x up until either it reaches the bound (x_low) or the size of the ZDD heap increases too much. Assumes that x is the top of a symmetry group. Checks x for symmetry to the adjacent variables. If symmetry is found, the symmetry group of x is merged with the symmetry group of the other variable. Returns the set of moves in case of success; ZDD_MV_OOM if memory is full.]

SideEffects [None]

SeeAlso []

Definition at line 33192 of file cuddInt.c.

33197 {
33198  Move *moves;
33199  Move *move;
33200  int y;
33201  int size;
33202  int limit_size = initial_size;
33203  int i, gytop;
33204 
33205  moves = NULL;
33206  y = cuddZddNextLow(table, x);
33207  while (y >= x_low) {
33208  gytop = table->subtableZ[y].next;
33209  if (cuddZddSymmCheck(table, y, x)) {
33210  /* Symmetry found, attach symm groups */
33211  table->subtableZ[y].next = x;
33212  i = table->subtableZ[x].next;
33213  while (table->subtableZ[i].next != (unsigned) x)
33214  i = table->subtableZ[i].next;
33215  table->subtableZ[i].next = gytop;
33216  }
33217  else if ((table->subtableZ[x].next == (unsigned) x) &&
33218  (table->subtableZ[y].next == (unsigned) y)) {
33219  /* x and y have self symmetry */
33220  size = cuddZddSwapInPlace(table, y, x);
33221  if (size == 0)
33222  goto cuddZddSymmSifting_upOutOfMem;
33223  move = (Move *)cuddDynamicAllocNode(table);
33224  if (move == NULL)
33225  goto cuddZddSymmSifting_upOutOfMem;
33226  move->x = y;
33227  move->y = x;
33228  move->size = size;
33229  move->next = moves;
33230  moves = move;
33231  if ((double)size >
33232  (double)limit_size * table->maxGrowth)
33233  return(moves);
33234  if (size < limit_size)
33235  limit_size = size;
33236  }
33237  else { /* Group move */
33238  size = zdd_group_move(table, y, x, &moves);
33239  if ((double)size >
33240  (double)limit_size * table->maxGrowth)
33241  return(moves);
33242  if (size < limit_size)
33243  limit_size = size;
33244  }
33245  x = gytop;
33246  y = cuddZddNextLow(table, x);
33247  }
33248 
33249  return(moves);
33250 
33251  cuddZddSymmSifting_upOutOfMem:
33252  while (moves != NULL) {
33253  move = moves->next;
33254  cuddDeallocMove(table, moves);
33255  moves = move;
33256  }
33257  return(ZDD_MV_OOM);
33258 
33259 } /* end of cuddZddSymmSifting_up */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
static int zdd_group_move(DdManager *table, int x, int y, Move **moves)
Definition: cuddInt.c:33423
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddInt.c:29836
#define ZDD_MV_OOM
Definition: cuddInt.c:32055
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
int cuddZddSymmCheck(DdManager *table, int x, int y)
Definition: cuddInt.c:32127
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSymmSiftingAux()

static int cuddZddSymmSiftingAux ( DdManager table,
int  x,
int  x_low,
int  x_high 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Given x_low <= x <= x_high moves x up and down between the boundaries.]

Description [Given x_low <= x <= x_high moves x up and down between the boundaries. Finds the best position and does the required changes. Assumes that x is not part of a symmetry group. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 32543 of file cuddInt.c.

32548 {
32549  Move *move;
32550  Move *move_up; /* list of up move */
32551  Move *move_down; /* list of down move */
32552  int initial_size;
32553  int result;
32554  int i;
32555  int topbot; /* index to either top or bottom of symmetry group */
32556  int init_group_size, final_group_size;
32557 
32558  initial_size = table->keysZ;
32559 
32560  move_down = NULL;
32561  move_up = NULL;
32562 
32563  /* Look for consecutive symmetries above x. */
32564  for (i = x; i > x_low; i--) {
32565  if (!cuddZddSymmCheck(table, i - 1, i))
32566  break;
32567  /* find top of i-1's symmetry */
32568  topbot = table->subtableZ[i - 1].next;
32569  table->subtableZ[i - 1].next = i;
32570  table->subtableZ[x].next = topbot;
32571  /* x is bottom of group so its symmetry is top of i-1's
32572  group */
32573  i = topbot + 1; /* add 1 for i--, new i is top of symm group */
32574  }
32575  /* Look for consecutive symmetries below x. */
32576  for (i = x; i < x_high; i++) {
32577  if (!cuddZddSymmCheck(table, i, i + 1))
32578  break;
32579  /* find bottom of i+1's symm group */
32580  topbot = i + 1;
32581  while ((unsigned) topbot < table->subtableZ[topbot].next)
32582  topbot = table->subtableZ[topbot].next;
32583 
32584  table->subtableZ[topbot].next = table->subtableZ[i].next;
32585  table->subtableZ[i].next = i + 1;
32586  i = topbot - 1; /* add 1 for i++,
32587  new i is bottom of symm group */
32588  }
32589 
32590  /* Now x maybe in the middle of a symmetry group. */
32591  if (x == x_low) { /* Sift down */
32592  /* Find bottom of x's symm group */
32593  while ((unsigned) x < table->subtableZ[x].next)
32594  x = table->subtableZ[x].next;
32595 
32596  i = table->subtableZ[x].next;
32597  init_group_size = x - i + 1;
32598 
32599  move_down = cuddZddSymmSifting_down(table, x, x_high,
32600  initial_size);
32601  /* after that point x --> x_high, unless early term */
32602  if (move_down == ZDD_MV_OOM)
32603  goto cuddZddSymmSiftingAuxOutOfMem;
32604 
32605  if (move_down == NULL ||
32606  table->subtableZ[move_down->y].next != move_down->y) {
32607  /* symmetry detected may have to make another complete
32608  pass */
32609  if (move_down != NULL)
32610  x = move_down->y;
32611  else
32612  x = table->subtableZ[x].next;
32613  i = x;
32614  while ((unsigned) i < table->subtableZ[i].next) {
32615  i = table->subtableZ[i].next;
32616  }
32617  final_group_size = i - x + 1;
32618 
32619  if (init_group_size == final_group_size) {
32620  /* No new symmetry groups detected,
32621  return to best position */
32622  result = cuddZddSymmSiftingBackward(table,
32623  move_down, initial_size);
32624  }
32625  else {
32626  initial_size = table->keysZ;
32627  move_up = cuddZddSymmSifting_up(table, x, x_low,
32628  initial_size);
32629  result = cuddZddSymmSiftingBackward(table, move_up,
32630  initial_size);
32631  }
32632  }
32633  else {
32634  result = cuddZddSymmSiftingBackward(table, move_down,
32635  initial_size);
32636  /* move backward and stop at best position */
32637  }
32638  if (!result)
32639  goto cuddZddSymmSiftingAuxOutOfMem;
32640  }
32641  else if (x == x_high) { /* Sift up */
32642  /* Find top of x's symm group */
32643  while ((unsigned) x < table->subtableZ[x].next)
32644  x = table->subtableZ[x].next;
32645  x = table->subtableZ[x].next;
32646 
32647  i = x;
32648  while ((unsigned) i < table->subtableZ[i].next) {
32649  i = table->subtableZ[i].next;
32650  }
32651  init_group_size = i - x + 1;
32652 
32653  move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size);
32654  /* after that point x --> x_low, unless early term */
32655  if (move_up == ZDD_MV_OOM)
32656  goto cuddZddSymmSiftingAuxOutOfMem;
32657 
32658  if (move_up == NULL ||
32659  table->subtableZ[move_up->x].next != move_up->x) {
32660  /* symmetry detected may have to make another complete
32661  pass */
32662  if (move_up != NULL)
32663  x = move_up->x;
32664  else {
32665  while ((unsigned) x < table->subtableZ[x].next)
32666  x = table->subtableZ[x].next;
32667  }
32668  i = table->subtableZ[x].next;
32669  final_group_size = x - i + 1;
32670 
32671  if (init_group_size == final_group_size) {
32672  /* No new symmetry groups detected,
32673  return to best position */
32674  result = cuddZddSymmSiftingBackward(table, move_up,
32675  initial_size);
32676  }
32677  else {
32678  initial_size = table->keysZ;
32679  move_down = cuddZddSymmSifting_down(table, x, x_high,
32680  initial_size);
32681  result = cuddZddSymmSiftingBackward(table, move_down,
32682  initial_size);
32683  }
32684  }
32685  else {
32686  result = cuddZddSymmSiftingBackward(table, move_up,
32687  initial_size);
32688  /* move backward and stop at best position */
32689  }
32690  if (!result)
32691  goto cuddZddSymmSiftingAuxOutOfMem;
32692  }
32693  else if ((x - x_low) > (x_high - x)) { /* must go down first:
32694  shorter */
32695  /* Find bottom of x's symm group */
32696  while ((unsigned) x < table->subtableZ[x].next)
32697  x = table->subtableZ[x].next;
32698 
32699  move_down = cuddZddSymmSifting_down(table, x, x_high,
32700  initial_size);
32701  /* after that point x --> x_high, unless early term */
32702  if (move_down == ZDD_MV_OOM)
32703  goto cuddZddSymmSiftingAuxOutOfMem;
32704 
32705  if (move_down != NULL) {
32706  x = move_down->y;
32707  }
32708  else {
32709  x = table->subtableZ[x].next;
32710  }
32711  i = x;
32712  while ((unsigned) i < table->subtableZ[i].next) {
32713  i = table->subtableZ[i].next;
32714  }
32715  init_group_size = i - x + 1;
32716 
32717  move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size);
32718  if (move_up == ZDD_MV_OOM)
32719  goto cuddZddSymmSiftingAuxOutOfMem;
32720 
32721  if (move_up == NULL ||
32722  table->subtableZ[move_up->x].next != move_up->x) {
32723  /* symmetry detected may have to make another complete
32724  pass */
32725  if (move_up != NULL) {
32726  x = move_up->x;
32727  }
32728  else {
32729  while ((unsigned) x < table->subtableZ[x].next)
32730  x = table->subtableZ[x].next;
32731  }
32732  i = table->subtableZ[x].next;
32733  final_group_size = x - i + 1;
32734 
32735  if (init_group_size == final_group_size) {
32736  /* No new symmetry groups detected,
32737  return to best position */
32738  result = cuddZddSymmSiftingBackward(table, move_up,
32739  initial_size);
32740  }
32741  else {
32742  while (move_down != NULL) {
32743  move = move_down->next;
32744  cuddDeallocMove(table, move_down);
32745  move_down = move;
32746  }
32747  initial_size = table->keysZ;
32748  move_down = cuddZddSymmSifting_down(table, x, x_high,
32749  initial_size);
32750  result = cuddZddSymmSiftingBackward(table, move_down,
32751  initial_size);
32752  }
32753  }
32754  else {
32755  result = cuddZddSymmSiftingBackward(table, move_up,
32756  initial_size);
32757  /* move backward and stop at best position */
32758  }
32759  if (!result)
32760  goto cuddZddSymmSiftingAuxOutOfMem;
32761  }
32762  else { /* moving up first:shorter */
32763  /* Find top of x's symmetry group */
32764  while ((unsigned) x < table->subtableZ[x].next)
32765  x = table->subtableZ[x].next;
32766  x = table->subtableZ[x].next;
32767 
32768  move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size);
32769  /* after that point x --> x_high, unless early term */
32770  if (move_up == ZDD_MV_OOM)
32771  goto cuddZddSymmSiftingAuxOutOfMem;
32772 
32773  if (move_up != NULL) {
32774  x = move_up->x;
32775  }
32776  else {
32777  while ((unsigned) x < table->subtableZ[x].next)
32778  x = table->subtableZ[x].next;
32779  }
32780  i = table->subtableZ[x].next;
32781  init_group_size = x - i + 1;
32782 
32783  move_down = cuddZddSymmSifting_down(table, x, x_high,
32784  initial_size);
32785  if (move_down == ZDD_MV_OOM)
32786  goto cuddZddSymmSiftingAuxOutOfMem;
32787 
32788  if (move_down == NULL ||
32789  table->subtableZ[move_down->y].next != move_down->y) {
32790  /* symmetry detected may have to make another complete
32791  pass */
32792  if (move_down != NULL) {
32793  x = move_down->y;
32794  }
32795  else {
32796  x = table->subtableZ[x].next;
32797  }
32798  i = x;
32799  while ((unsigned) i < table->subtableZ[i].next) {
32800  i = table->subtableZ[i].next;
32801  }
32802  final_group_size = i - x + 1;
32803 
32804  if (init_group_size == final_group_size) {
32805  /* No new symmetries detected,
32806  go back to best position */
32807  result = cuddZddSymmSiftingBackward(table, move_down,
32808  initial_size);
32809  }
32810  else {
32811  while (move_up != NULL) {
32812  move = move_up->next;
32813  cuddDeallocMove(table, move_up);
32814  move_up = move;
32815  }
32816  initial_size = table->keysZ;
32817  move_up = cuddZddSymmSifting_up(table, x, x_low,
32818  initial_size);
32819  result = cuddZddSymmSiftingBackward(table, move_up,
32820  initial_size);
32821  }
32822  }
32823  else {
32824  result = cuddZddSymmSiftingBackward(table, move_down,
32825  initial_size);
32826  /* move backward and stop at best position */
32827  }
32828  if (!result)
32829  goto cuddZddSymmSiftingAuxOutOfMem;
32830  }
32831 
32832  while (move_down != NULL) {
32833  move = move_down->next;
32834  cuddDeallocMove(table, move_down);
32835  move_down = move;
32836  }
32837  while (move_up != NULL) {
32838  move = move_up->next;
32839  cuddDeallocMove(table, move_up);
32840  move_up = move;
32841  }
32842 
32843  return(1);
32844 
32845  cuddZddSymmSiftingAuxOutOfMem:
32846  if (move_down != ZDD_MV_OOM) {
32847  while (move_down != NULL) {
32848  move = move_down->next;
32849  cuddDeallocMove(table, move_down);
32850  move_down = move;
32851  }
32852  }
32853  if (move_up != ZDD_MV_OOM) {
32854  while (move_up != NULL) {
32855  move = move_up->next;
32856  cuddDeallocMove(table, move_up);
32857  move_up = move;
32858  }
32859  }
32860 
32861  return(0);
32862 
32863 } /* end of cuddZddSymmSiftingAux */
static Move * cuddZddSymmSifting_up(DdManager *table, int x, int x_low, int initial_size)
Definition: cuddInt.c:33192
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdHalfWord x
Definition: cuddInt.h:470
static Move * cuddZddSymmSifting_down(DdManager *table, int x, int x_high, int initial_size)
Definition: cuddInt.c:33280
#define ZDD_MV_OOM
Definition: cuddInt.c:32055
int cuddZddSymmCheck(DdManager *table, int x, int y)
Definition: cuddInt.c:32127
static int result
Definition: cuddInt.c:7466
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
static int cuddZddSymmSiftingBackward(DdManager *table, Move *moves, int size)
Definition: cuddInt.c:33371
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSymmSiftingBackward()

static int cuddZddSymmSiftingBackward ( DdManager table,
Move moves,
int  size 
)
static

Function********************************************************************

Synopsis [Given a set of moves, returns the ZDD heap to the position giving the minimum size.]

Description [Given a set of moves, returns the ZDD heap to the position giving the minimum size. In case of ties, returns to the closest position giving the minimum size. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 33371 of file cuddInt.c.

33375 {
33376  int i;
33377  int i_best;
33378  Move *move;
33379  int res;
33380 
33381  i_best = -1;
33382  for (move = moves, i = 0; move != NULL; move = move->next, i++) {
33383  if (move->size < size) {
33384  i_best = i;
33385  size = move->size;
33386  }
33387  }
33388 
33389  for (move = moves, i = 0; move != NULL; move = move->next, i++) {
33390  if (i == i_best) break;
33391  if ((table->subtableZ[move->x].next == move->x) &&
33392  (table->subtableZ[move->y].next == move->y)) {
33393  res = cuddZddSwapInPlace(table, move->x, move->y);
33394  if (!res) return(0);
33395  }
33396  else { /* Group move necessary */
33397  res = zdd_group_move_backward(table, move->x, move->y);
33398  }
33399  if (i_best == -1 && res == size)
33400  break;
33401  }
33402 
33403  return(1);
33404 
33405 } /* end of cuddZddSymmSiftingBackward */
Definition: cuddInt.h:469
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473
DdSubtable * subtableZ
Definition: cuddInt.h:350
static int zdd_group_move_backward(DdManager *table, int x, int y)
Definition: cuddInt.c:33530

◆ cuddZddSymmSiftingConv()

int cuddZddSymmSiftingConv ( DdManager table,
int  lower,
int  upper 
)

Function********************************************************************

Synopsis [Symmetric sifting to convergence algorithm for ZDDs.]

Description [Symmetric sifting to convergence algorithm for ZDDs. Assumes that no dead nodes are present.

  1. Order all the variables according to the number of entries in each unique subtable.
  2. Sift the variable up and down, remembering each time the total size of the ZDD heap and grouping variables that are symmetric.
  3. Select the best permutation.
  4. Repeat 3 and 4 for all variables.
  5. Repeat 1-4 until no further improvement.

Returns 1 plus the number of symmetric variables if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [cuddZddSymmSifting]

Definition at line 32357 of file cuddInt.c.

32361 {
32362  int i;
32363  int *var;
32364  int nvars;
32365  int initialSize;
32366  int x;
32367  int result;
32368  int symvars;
32369  int symgroups;
32370  int classes;
32371  int iteration;
32372 #ifdef DD_STATS
32373  int previousSize;
32374 #endif
32375 
32376  initialSize = table->keysZ;
32377 
32378  nvars = table->sizeZ;
32379 
32380  /* Find order in which to sift variables. */
32381  var = NULL;
32382  zdd_entry = ALLOC(int, nvars);
32383  if (zdd_entry == NULL) {
32384  table->errorCode = CUDD_MEMORY_OUT;
32385  goto cuddZddSymmSiftingConvOutOfMem;
32386  }
32387  var = ALLOC(int, nvars);
32388  if (var == NULL) {
32389  table->errorCode = CUDD_MEMORY_OUT;
32390  goto cuddZddSymmSiftingConvOutOfMem;
32391  }
32392 
32393  for (i = 0; i < nvars; i++) {
32394  x = table->permZ[i];
32395  zdd_entry[i] = table->subtableZ[x].keys;
32396  var[i] = i;
32397  }
32398 
32399  qsort((void *)var, nvars, sizeof(int), (DD_QSFP)cuddZddUniqueCompare);
32400 
32401  /* Initialize the symmetry of each subtable to itself
32402  ** for first pass of converging symmetric sifting.
32403  */
32404  for (i = lower; i <= upper; i++)
32405  table->subtableZ[i].next = i;
32406 
32407  iteration = ddMin(table->siftMaxVar, table->sizeZ);
32408  for (i = 0; i < iteration; i++) {
32409  if (zddTotalNumberSwapping >= table->siftMaxSwap)
32410  break;
32411  if (util_cpu_time() - table->startTime > table->timeLimit) {
32412  table->autoDynZ = 0; /* prevent further reordering */
32413  break;
32414  }
32415  x = table->permZ[var[i]];
32416  if (x < lower || x > upper) continue;
32417  /* Only sift if not in symmetry group already. */
32418  if (table->subtableZ[x].next == (unsigned) x) {
32419 #ifdef DD_STATS
32420  previousSize = table->keysZ;
32421 #endif
32422  result = cuddZddSymmSiftingAux(table, x, lower, upper);
32423  if (!result)
32424  goto cuddZddSymmSiftingConvOutOfMem;
32425 #ifdef DD_STATS
32426  if (table->keysZ < (unsigned) previousSize) {
32427  (void) fprintf(table->out,"-");
32428  } else if (table->keysZ > (unsigned) previousSize) {
32429  (void) fprintf(table->out,"+");
32430 #ifdef DD_VERBOSE
32431  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]);
32432 #endif
32433  } else {
32434  (void) fprintf(table->out,"=");
32435  }
32436  fflush(table->out);
32437 #endif
32438  }
32439  }
32440 
32441  /* Sifting now until convergence. */
32442  while ((unsigned) initialSize > table->keysZ) {
32443  initialSize = table->keysZ;
32444 #ifdef DD_STATS
32445  (void) fprintf(table->out,"\n");
32446 #endif
32447  /* Here we consider only one representative for each symmetry class. */
32448  for (x = lower, classes = 0; x <= upper; x++, classes++) {
32449  while ((unsigned) x < table->subtableZ[x].next)
32450  x = table->subtableZ[x].next;
32451  /* Here x is the largest index in a group.
32452  ** Groups consists of adjacent variables.
32453  ** Hence, the next increment of x will move it to a new group.
32454  */
32455  i = table->invpermZ[x];
32456  zdd_entry[i] = table->subtableZ[x].keys;
32457  var[classes] = i;
32458  }
32459 
32460  qsort((void *)var,classes,sizeof(int),(DD_QSFP)cuddZddUniqueCompare);
32461 
32462  /* Now sift. */
32463  iteration = ddMin(table->siftMaxVar, nvars);
32464  for (i = 0; i < iteration; i++) {
32465  if (zddTotalNumberSwapping >= table->siftMaxSwap)
32466  break;
32467  if (util_cpu_time() - table->startTime > table->timeLimit) {
32468  table->autoDynZ = 0; /* prevent further reordering */
32469  break;
32470  }
32471  x = table->permZ[var[i]];
32472  if ((unsigned) x >= table->subtableZ[x].next) {
32473 #ifdef DD_STATS
32474  previousSize = table->keysZ;
32475 #endif
32476  result = cuddZddSymmSiftingConvAux(table, x, lower, upper);
32477  if (!result)
32478  goto cuddZddSymmSiftingConvOutOfMem;
32479 #ifdef DD_STATS
32480  if (table->keysZ < (unsigned) previousSize) {
32481  (void) fprintf(table->out,"-");
32482  } else if (table->keysZ > (unsigned) previousSize) {
32483  (void) fprintf(table->out,"+");
32484 #ifdef DD_VERBOSE
32485  (void) fprintf(table->out,"\nSize increased from %d to %d while sifting variable %d\n", previousSize, table->keysZ, var[i]);
32486 #endif
32487  } else {
32488  (void) fprintf(table->out,"=");
32489  }
32490  fflush(table->out);
32491 #endif
32492  }
32493  } /* for */
32494  }
32495 
32496  cuddZddSymmSummary(table, lower, upper, &symvars, &symgroups);
32497 
32498 #ifdef DD_STATS
32499  (void) fprintf(table->out,"\n#:S_SIFTING %8d: symmetric variables\n",
32500  symvars);
32501  (void) fprintf(table->out,"#:G_SIFTING %8d: symmetric groups\n",
32502  symgroups);
32503 #endif
32504 
32505  FREE(var);
32506  FREE(zdd_entry);
32507 
32508  return(1+symvars);
32509 
32510  cuddZddSymmSiftingConvOutOfMem:
32511 
32512  if (zdd_entry != NULL)
32513  FREE(zdd_entry);
32514  if (var != NULL)
32515  FREE(var);
32516 
32517  return(0);
32518 
32519 } /* end of cuddZddSymmSiftingConv */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:302
unsigned long startTime
Definition: cuddInt.h:426
int * invpermZ
Definition: cuddInt.h:372
int * zdd_entry
Definition: cuddInt.c:29545
int * permZ
Definition: cuddInt.h:370
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static void cuddZddSymmSummary(DdManager *table, int lower, int upper, int *symvars, int *symgroups)
Definition: cuddInt.c:33613
int cuddZddUniqueCompare(int *ptr_x, int *ptr_y)
Definition: cuddInt.c:29860
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: util.c:34
int zddTotalNumberSwapping
Definition: cuddInt.c:28565
int siftMaxVar
Definition: cuddInt.h:395
int sizeZ
Definition: cuddInt.h:346
static int result
Definition: cuddInt.c:7466
unsigned int next
Definition: cuddInt.h:317
int autoDynZ
Definition: cuddInt.h:401
static int cuddZddSymmSiftingAux(DdManager *table, int x, int x_low, int x_high)
Definition: cuddInt.c:32543
static int cuddZddSymmSiftingConvAux(DdManager *table, int x, int x_low, int x_high)
Definition: cuddInt.c:32883
unsigned int keysZ
Definition: cuddInt.h:354
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSymmSiftingConvAux()

static int cuddZddSymmSiftingConvAux ( DdManager table,
int  x,
int  x_low,
int  x_high 
)
static

Function********************************************************************

Synopsis [Given x_low <= x <= x_high moves x up and down between the boundaries.]

Description [Given x_low <= x <= x_high moves x up and down between the boundaries. Finds the best position and does the required changes. Assumes that x is either an isolated variable, or it is the bottom of a symmetry group. All symmetries may not have been found, because of exceeded growth limit. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 32883 of file cuddInt.c.

32888 {
32889  Move *move;
32890  Move *move_up; /* list of up move */
32891  Move *move_down; /* list of down move */
32892  int initial_size;
32893  int result;
32894  int i;
32895  int init_group_size, final_group_size;
32896 
32897  initial_size = table->keysZ;
32898 
32899  move_down = NULL;
32900  move_up = NULL;
32901 
32902  if (x == x_low) { /* Sift down */
32903  i = table->subtableZ[x].next;
32904  init_group_size = x - i + 1;
32905 
32906  move_down = cuddZddSymmSifting_down(table, x, x_high,
32907  initial_size);
32908  /* after that point x --> x_high, unless early term */
32909  if (move_down == ZDD_MV_OOM)
32910  goto cuddZddSymmSiftingConvAuxOutOfMem;
32911 
32912  if (move_down == NULL ||
32913  table->subtableZ[move_down->y].next != move_down->y) {
32914  /* symmetry detected may have to make another complete
32915  pass */
32916  if (move_down != NULL)
32917  x = move_down->y;
32918  else {
32919  while ((unsigned) x < table->subtableZ[x].next)
32920  x = table->subtableZ[x].next;
32921  x = table->subtableZ[x].next;
32922  }
32923  i = x;
32924  while ((unsigned) i < table->subtableZ[i].next) {
32925  i = table->subtableZ[i].next;
32926  }
32927  final_group_size = i - x + 1;
32928 
32929  if (init_group_size == final_group_size) {
32930  /* No new symmetries detected,
32931  go back to best position */
32932  result = cuddZddSymmSiftingBackward(table, move_down,
32933  initial_size);
32934  }
32935  else {
32936  initial_size = table->keysZ;
32937  move_up = cuddZddSymmSifting_up(table, x, x_low,
32938  initial_size);
32939  result = cuddZddSymmSiftingBackward(table, move_up,
32940  initial_size);
32941  }
32942  }
32943  else {
32944  result = cuddZddSymmSiftingBackward(table, move_down,
32945  initial_size);
32946  /* move backward and stop at best position */
32947  }
32948  if (!result)
32949  goto cuddZddSymmSiftingConvAuxOutOfMem;
32950  }
32951  else if (x == x_high) { /* Sift up */
32952  /* Find top of x's symm group */
32953  while ((unsigned) x < table->subtableZ[x].next)
32954  x = table->subtableZ[x].next;
32955  x = table->subtableZ[x].next;
32956 
32957  i = x;
32958  while ((unsigned) i < table->subtableZ[i].next) {
32959  i = table->subtableZ[i].next;
32960  }
32961  init_group_size = i - x + 1;
32962 
32963  move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size);
32964  /* after that point x --> x_low, unless early term */
32965  if (move_up == ZDD_MV_OOM)
32966  goto cuddZddSymmSiftingConvAuxOutOfMem;
32967 
32968  if (move_up == NULL ||
32969  table->subtableZ[move_up->x].next != move_up->x) {
32970  /* symmetry detected may have to make another complete
32971  pass */
32972  if (move_up != NULL)
32973  x = move_up->x;
32974  else {
32975  while ((unsigned) x < table->subtableZ[x].next)
32976  x = table->subtableZ[x].next;
32977  }
32978  i = table->subtableZ[x].next;
32979  final_group_size = x - i + 1;
32980 
32981  if (init_group_size == final_group_size) {
32982  /* No new symmetry groups detected,
32983  return to best position */
32984  result = cuddZddSymmSiftingBackward(table, move_up,
32985  initial_size);
32986  }
32987  else {
32988  initial_size = table->keysZ;
32989  move_down = cuddZddSymmSifting_down(table, x, x_high,
32990  initial_size);
32991  result = cuddZddSymmSiftingBackward(table, move_down,
32992  initial_size);
32993  }
32994  }
32995  else {
32996  result = cuddZddSymmSiftingBackward(table, move_up,
32997  initial_size);
32998  /* move backward and stop at best position */
32999  }
33000  if (!result)
33001  goto cuddZddSymmSiftingConvAuxOutOfMem;
33002  }
33003  else if ((x - x_low) > (x_high - x)) { /* must go down first:
33004  shorter */
33005  move_down = cuddZddSymmSifting_down(table, x, x_high,
33006  initial_size);
33007  /* after that point x --> x_high */
33008  if (move_down == ZDD_MV_OOM)
33009  goto cuddZddSymmSiftingConvAuxOutOfMem;
33010 
33011  if (move_down != NULL) {
33012  x = move_down->y;
33013  }
33014  else {
33015  while ((unsigned) x < table->subtableZ[x].next)
33016  x = table->subtableZ[x].next;
33017  x = table->subtableZ[x].next;
33018  }
33019  i = x;
33020  while ((unsigned) i < table->subtableZ[i].next) {
33021  i = table->subtableZ[i].next;
33022  }
33023  init_group_size = i - x + 1;
33024 
33025  move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size);
33026  if (move_up == ZDD_MV_OOM)
33027  goto cuddZddSymmSiftingConvAuxOutOfMem;
33028 
33029  if (move_up == NULL ||
33030  table->subtableZ[move_up->x].next != move_up->x) {
33031  /* symmetry detected may have to make another complete
33032  pass */
33033  if (move_up != NULL) {
33034  x = move_up->x;
33035  }
33036  else {
33037  while ((unsigned) x < table->subtableZ[x].next)
33038  x = table->subtableZ[x].next;
33039  }
33040  i = table->subtableZ[x].next;
33041  final_group_size = x - i + 1;
33042 
33043  if (init_group_size == final_group_size) {
33044  /* No new symmetry groups detected,
33045  return to best position */
33046  result = cuddZddSymmSiftingBackward(table, move_up,
33047  initial_size);
33048  }
33049  else {
33050  while (move_down != NULL) {
33051  move = move_down->next;
33052  cuddDeallocMove(table, move_down);
33053  move_down = move;
33054  }
33055  initial_size = table->keysZ;
33056  move_down = cuddZddSymmSifting_down(table, x, x_high,
33057  initial_size);
33058  result = cuddZddSymmSiftingBackward(table, move_down,
33059  initial_size);
33060  }
33061  }
33062  else {
33063  result = cuddZddSymmSiftingBackward(table, move_up,
33064  initial_size);
33065  /* move backward and stop at best position */
33066  }
33067  if (!result)
33068  goto cuddZddSymmSiftingConvAuxOutOfMem;
33069  }
33070  else { /* moving up first:shorter */
33071  /* Find top of x's symmetry group */
33072  x = table->subtableZ[x].next;
33073 
33074  move_up = cuddZddSymmSifting_up(table, x, x_low, initial_size);
33075  /* after that point x --> x_high, unless early term */
33076  if (move_up == ZDD_MV_OOM)
33077  goto cuddZddSymmSiftingConvAuxOutOfMem;
33078 
33079  if (move_up != NULL) {
33080  x = move_up->x;
33081  }
33082  else {
33083  while ((unsigned) x < table->subtableZ[x].next)
33084  x = table->subtableZ[x].next;
33085  }
33086  i = table->subtableZ[x].next;
33087  init_group_size = x - i + 1;
33088 
33089  move_down = cuddZddSymmSifting_down(table, x, x_high,
33090  initial_size);
33091  if (move_down == ZDD_MV_OOM)
33092  goto cuddZddSymmSiftingConvAuxOutOfMem;
33093 
33094  if (move_down == NULL ||
33095  table->subtableZ[move_down->y].next != move_down->y) {
33096  /* symmetry detected may have to make another complete
33097  pass */
33098  if (move_down != NULL) {
33099  x = move_down->y;
33100  }
33101  else {
33102  while ((unsigned) x < table->subtableZ[x].next)
33103  x = table->subtableZ[x].next;
33104  x = table->subtableZ[x].next;
33105  }
33106  i = x;
33107  while ((unsigned) i < table->subtableZ[i].next) {
33108  i = table->subtableZ[i].next;
33109  }
33110  final_group_size = i - x + 1;
33111 
33112  if (init_group_size == final_group_size) {
33113  /* No new symmetries detected,
33114  go back to best position */
33115  result = cuddZddSymmSiftingBackward(table, move_down,
33116  initial_size);
33117  }
33118  else {
33119  while (move_up != NULL) {
33120  move = move_up->next;
33121  cuddDeallocMove(table, move_up);
33122  move_up = move;
33123  }
33124  initial_size = table->keysZ;
33125  move_up = cuddZddSymmSifting_up(table, x, x_low,
33126  initial_size);
33127  result = cuddZddSymmSiftingBackward(table, move_up,
33128  initial_size);
33129  }
33130  }
33131  else {
33132  result = cuddZddSymmSiftingBackward(table, move_down,
33133  initial_size);
33134  /* move backward and stop at best position */
33135  }
33136  if (!result)
33137  goto cuddZddSymmSiftingConvAuxOutOfMem;
33138  }
33139 
33140  while (move_down != NULL) {
33141  move = move_down->next;
33142  cuddDeallocMove(table, move_down);
33143  move_down = move;
33144  }
33145  while (move_up != NULL) {
33146  move = move_up->next;
33147  cuddDeallocMove(table, move_up);
33148  move_up = move;
33149  }
33150 
33151  return(1);
33152 
33153  cuddZddSymmSiftingConvAuxOutOfMem:
33154  if (move_down != ZDD_MV_OOM) {
33155  while (move_down != NULL) {
33156  move = move_down->next;
33157  cuddDeallocMove(table, move_down);
33158  move_down = move;
33159  }
33160  }
33161  if (move_up != ZDD_MV_OOM) {
33162  while (move_up != NULL) {
33163  move = move_up->next;
33164  cuddDeallocMove(table, move_up);
33165  move_up = move;
33166  }
33167  }
33168 
33169  return(0);
33170 
33171 } /* end of cuddZddSymmSiftingConvAux */
static Move * cuddZddSymmSifting_up(DdManager *table, int x, int x_low, int initial_size)
Definition: cuddInt.c:33192
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdHalfWord x
Definition: cuddInt.h:470
static Move * cuddZddSymmSifting_down(DdManager *table, int x, int x_high, int initial_size)
Definition: cuddInt.c:33280
#define ZDD_MV_OOM
Definition: cuddInt.c:32055
static int result
Definition: cuddInt.c:7466
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
static int cuddZddSymmSiftingBackward(DdManager *table, Move *moves, int size)
Definition: cuddInt.c:33371
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddSymmSummary()

static void cuddZddSymmSummary ( DdManager table,
int  lower,
int  upper,
int *  symvars,
int *  symgroups 
)
static

Function********************************************************************

Synopsis [Counts numbers of symmetric variables and symmetry groups.]

Description []

SideEffects [None]

Definition at line 33613 of file cuddInt.c.

33619 {
33620  int i,x,gbot;
33621  int TotalSymm = 0;
33622  int TotalSymmGroups = 0;
33623 
33624  for (i = lower; i <= upper; i++) {
33625  if (table->subtableZ[i].next != (unsigned) i) {
33626  TotalSymmGroups++;
33627  x = i;
33628  do {
33629  TotalSymm++;
33630  gbot = x;
33631  x = table->subtableZ[x].next;
33632  } while (x != i);
33633 #ifdef DD_DEBUG
33634  assert(table->subtableZ[gbot].next == (unsigned) i);
33635 #endif
33636  i = gbot;
33637  }
33638  }
33639  *symvars = TotalSymm;
33640  *symgroups = TotalSymmGroups;
33641 
33642  return;
33643 
33644 } /* end of cuddZddSymmSummary */
#define assert(ex)
Definition: util.h:141
unsigned int next
Definition: cuddInt.h:317
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddTreeSifting()

int cuddZddTreeSifting ( DdManager table,
Cudd_ReorderingType  method 
)

AutomaticEnd Function********************************************************************

Synopsis [Tree sifting algorithm for ZDDs.]

Description [Tree sifting algorithm for ZDDs. Assumes that a tree representing a group hierarchy is passed as a parameter. It then reorders each group in postorder fashion by calling zddTreeSiftingAux. Assumes that no dead nodes are present. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 26558 of file cuddInt.c.

26561 {
26562  int i;
26563  int nvars;
26564  int result;
26565  int tempTree;
26566 
26567  /* If no tree is provided we create a temporary one in which all
26568  ** variables are in a single group. After reordering this tree is
26569  ** destroyed.
26570  */
26571  tempTree = table->treeZ == NULL;
26572  if (tempTree) {
26573  table->treeZ = Mtr_InitGroupTree(0,table->sizeZ);
26574  table->treeZ->index = table->invpermZ[0];
26575  }
26576  nvars = table->sizeZ;
26577 
26578 #ifdef DD_DEBUG
26579  if (pr > 0 && !tempTree)
26580  (void) fprintf(table->out,"cuddZddTreeSifting:");
26581  Mtr_PrintGroups(table->treeZ,pr <= 0);
26582 #endif
26583 #if 0
26584  /* Debugging code. */
26585  if (table->tree && table->treeZ) {
26586  (void) fprintf(table->out,"\n");
26587  Mtr_PrintGroups(table->tree, 0);
26588  cuddPrintVarGroups(table,table->tree,0,0);
26589  for (i = 0; i < table->size; i++) {
26590  (void) fprintf(table->out,"%s%d",
26591  (i == 0) ? "" : ",", table->invperm[i]);
26592  }
26593  (void) fprintf(table->out,"\n");
26594  for (i = 0; i < table->size; i++) {
26595  (void) fprintf(table->out,"%s%d",
26596  (i == 0) ? "" : ",", table->perm[i]);
26597  }
26598  (void) fprintf(table->out,"\n\n");
26599  Mtr_PrintGroups(table->treeZ,0);
26600  cuddPrintVarGroups(table,table->treeZ,1,0);
26601  for (i = 0; i < table->sizeZ; i++) {
26602  (void) fprintf(table->out,"%s%d",
26603  (i == 0) ? "" : ",", table->invpermZ[i]);
26604  }
26605  (void) fprintf(table->out,"\n");
26606  for (i = 0; i < table->sizeZ; i++) {
26607  (void) fprintf(table->out,"%s%d",
26608  (i == 0) ? "" : ",", table->permZ[i]);
26609  }
26610  (void) fprintf(table->out,"\n");
26611  }
26612  /* End of debugging code. */
26613 #endif
26614 #ifdef DD_STATS
26615  extsymmcalls = 0;
26616  extsymm = 0;
26617  secdiffcalls = 0;
26618  secdiff = 0;
26619  secdiffmisfire = 0;
26620 
26621  (void) fprintf(table->out,"\n");
26622  if (!tempTree)
26623  (void) fprintf(table->out,"#:IM_NODES %8d: group tree nodes\n",
26624  zddCountInternalMtrNodes(table,table->treeZ));
26625 #endif
26626 
26627  /* Initialize the group of each subtable to itself. Initially
26628  ** there are no groups. Groups are created according to the tree
26629  ** structure in postorder fashion.
26630  */
26631  for (i = 0; i < nvars; i++)
26632  table->subtableZ[i].next = i;
26633 
26634  /* Reorder. */
26635  result = zddTreeSiftingAux(table, table->treeZ, method);
26636 
26637 #ifdef DD_STATS /* print stats */
26638  if (!tempTree && method == CUDD_REORDER_GROUP_SIFT &&
26639  (table->groupcheck == CUDD_GROUP_CHECK7 ||
26640  table->groupcheck == CUDD_GROUP_CHECK5)) {
26641  (void) fprintf(table->out,"\nextsymmcalls = %d\n",extsymmcalls);
26642  (void) fprintf(table->out,"extsymm = %d",extsymm);
26643  }
26644  if (!tempTree && method == CUDD_REORDER_GROUP_SIFT &&
26645  table->groupcheck == CUDD_GROUP_CHECK7) {
26646  (void) fprintf(table->out,"\nsecdiffcalls = %d\n",secdiffcalls);
26647  (void) fprintf(table->out,"secdiff = %d\n",secdiff);
26648  (void) fprintf(table->out,"secdiffmisfire = %d",secdiffmisfire);
26649  }
26650 #endif
26651 
26652  if (tempTree)
26653  Cudd_FreeZddTree(table);
26654  return(result);
26655 
26656 } /* end of cuddZddTreeSifting */
Cudd_AggregationType groupcheck
Definition: cuddInt.h:410
int * invpermZ
Definition: cuddInt.h:372
int size
Definition: cuddInt.h:345
int * permZ
Definition: cuddInt.h:370
MtrNode * tree
Definition: cuddInt.h:408
void Cudd_FreeZddTree(DdManager *dd)
Definition: cuddInt.c:1831
void cuddPrintVarGroups(DdManager *dd, MtrNode *root, int zdd, int silent)
Definition: cuddInt.c:5866
MtrHalfWord index
Definition: mtr.h:130
FILE * out
Definition: cuddInt.h:423
void Mtr_PrintGroups(MtrNode *root, int silent)
Definition: mtr.c:773
static int zddTreeSiftingAux(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddInt.c:26675
MtrNode * Mtr_InitGroupTree(int lower, int size)
Definition: mtr.c:410
int sizeZ
Definition: cuddInt.h:346
static int result
Definition: cuddInt.c:7466
unsigned int next
Definition: cuddInt.h:317
MtrNode * treeZ
Definition: cuddInt.h:409
int * invperm
Definition: cuddInt.h:371
int * perm
Definition: cuddInt.h:369
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ cuddZddUnateProduct()

DdNode* cuddZddUnateProduct ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddUnateProduct.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddUnateProduct]

Definition at line 25384 of file cuddInt.c.

25388 {
25389  int v, top_f, top_g;
25390  DdNode *term1, *term2, *term3, *term4;
25391  DdNode *sum1, *sum2;
25392  DdNode *f0, *f1, *g0, *g1;
25393  DdNode *r;
25394  DdNode *one = DD_ONE(dd);
25395  DdNode *zero = DD_ZERO(dd);
25396  int flag;
25397 
25398  statLine(dd);
25399  if (f == zero || g == zero)
25400  return(zero);
25401  if (f == one)
25402  return(g);
25403  if (g == one)
25404  return(f);
25405 
25406  top_f = dd->permZ[f->index];
25407  top_g = dd->permZ[g->index];
25408 
25409  if (top_f > top_g)
25410  return(cuddZddUnateProduct(dd, g, f));
25411 
25412  /* Check cache */
25414  if (r)
25415  return(r);
25416 
25417  v = f->index; /* either yi or zi */
25418  flag = cuddZddGetCofactors2(dd, f, v, &f1, &f0);
25419  if (flag == 1)
25420  return(NULL);
25421  Cudd_Ref(f1);
25422  Cudd_Ref(f0);
25423  flag = cuddZddGetCofactors2(dd, g, v, &g1, &g0);
25424  if (flag == 1) {
25425  Cudd_RecursiveDerefZdd(dd, f1);
25426  Cudd_RecursiveDerefZdd(dd, f0);
25427  return(NULL);
25428  }
25429  Cudd_Ref(g1);
25430  Cudd_Ref(g0);
25431 
25432  term1 = cuddZddUnateProduct(dd, f1, g1);
25433  if (term1 == NULL) {
25434  Cudd_RecursiveDerefZdd(dd, f1);
25435  Cudd_RecursiveDerefZdd(dd, f0);
25436  Cudd_RecursiveDerefZdd(dd, g1);
25437  Cudd_RecursiveDerefZdd(dd, g0);
25438  return(NULL);
25439  }
25440  Cudd_Ref(term1);
25441  term2 = cuddZddUnateProduct(dd, f1, g0);
25442  if (term2 == NULL) {
25443  Cudd_RecursiveDerefZdd(dd, f1);
25444  Cudd_RecursiveDerefZdd(dd, f0);
25445  Cudd_RecursiveDerefZdd(dd, g1);
25446  Cudd_RecursiveDerefZdd(dd, g0);
25447  Cudd_RecursiveDerefZdd(dd, term1);
25448  return(NULL);
25449  }
25450  Cudd_Ref(term2);
25451  term3 = cuddZddUnateProduct(dd, f0, g1);
25452  if (term3 == NULL) {
25453  Cudd_RecursiveDerefZdd(dd, f1);
25454  Cudd_RecursiveDerefZdd(dd, f0);
25455  Cudd_RecursiveDerefZdd(dd, g1);
25456  Cudd_RecursiveDerefZdd(dd, g0);
25457  Cudd_RecursiveDerefZdd(dd, term1);
25458  Cudd_RecursiveDerefZdd(dd, term2);
25459  return(NULL);
25460  }
25461  Cudd_Ref(term3);
25462  term4 = cuddZddUnateProduct(dd, f0, g0);
25463  if (term4 == NULL) {
25464  Cudd_RecursiveDerefZdd(dd, f1);
25465  Cudd_RecursiveDerefZdd(dd, f0);
25466  Cudd_RecursiveDerefZdd(dd, g1);
25467  Cudd_RecursiveDerefZdd(dd, g0);
25468  Cudd_RecursiveDerefZdd(dd, term1);
25469  Cudd_RecursiveDerefZdd(dd, term2);
25470  Cudd_RecursiveDerefZdd(dd, term3);
25471  return(NULL);
25472  }
25473  Cudd_Ref(term4);
25474  Cudd_RecursiveDerefZdd(dd, f1);
25475  Cudd_RecursiveDerefZdd(dd, f0);
25476  Cudd_RecursiveDerefZdd(dd, g1);
25477  Cudd_RecursiveDerefZdd(dd, g0);
25478  sum1 = cuddZddUnion(dd, term1, term2);
25479  if (sum1 == NULL) {
25480  Cudd_RecursiveDerefZdd(dd, term1);
25481  Cudd_RecursiveDerefZdd(dd, term2);
25482  Cudd_RecursiveDerefZdd(dd, term3);
25483  Cudd_RecursiveDerefZdd(dd, term4);
25484  return(NULL);
25485  }
25486  Cudd_Ref(sum1);
25487  Cudd_RecursiveDerefZdd(dd, term1);
25488  Cudd_RecursiveDerefZdd(dd, term2);
25489  sum2 = cuddZddUnion(dd, sum1, term3);
25490  if (sum2 == NULL) {
25491  Cudd_RecursiveDerefZdd(dd, term3);
25492  Cudd_RecursiveDerefZdd(dd, term4);
25493  Cudd_RecursiveDerefZdd(dd, sum1);
25494  return(NULL);
25495  }
25496  Cudd_Ref(sum2);
25497  Cudd_RecursiveDerefZdd(dd, sum1);
25498  Cudd_RecursiveDerefZdd(dd, term3);
25499  r = cuddZddGetNode(dd, v, sum2, term4);
25500  if (r == NULL) {
25501  Cudd_RecursiveDerefZdd(dd, term4);
25502  Cudd_RecursiveDerefZdd(dd, sum2);
25503  return(NULL);
25504  }
25505  Cudd_Ref(r);
25506  Cudd_RecursiveDerefZdd(dd, sum2);
25507  Cudd_RecursiveDerefZdd(dd, term4);
25508 
25509  cuddCacheInsert2(dd, cuddZddUnateProduct, f, g, r);
25510  Cudd_Deref(r);
25511  return(r);
25512 
25513 } /* end of cuddZddUnateProduct */
Definition: cudd.h:264
static DdNode * one
Definition: cuddInt.c:16562
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
void Cudd_Ref(DdNode *n)
Definition: cuddInt.c:14002
int cuddZddGetCofactors2(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0)
Definition: cuddInt.c:26254
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddInt.c:31404
DdNode * cuddZddUnateProduct(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:25384
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddInt.c:20408
DdHalfWord index
Definition: cudd.h:265
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void Cudd_Deref(DdNode *node)
Definition: cuddInt.c:14198
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddUndoMoves()

static Move * cuddZddUndoMoves ( DdManager table,
Move moves 
)
static

Function********************************************************************

Synopsis [Given a set of moves, returns the ZDD heap to the order in effect before the moves.]

Description [Given a set of moves, returns the ZDD heap to the order in effect before the moves. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 29394 of file cuddInt.c.

29397 {
29398  Move *invmoves = NULL;
29399  Move *move;
29400  Move *invmove;
29401  int size;
29402 
29403  for (move = moves; move != NULL; move = move->next) {
29404  invmove = (Move *) cuddDynamicAllocNode(table);
29405  if (invmove == NULL) goto cuddZddUndoMovesOutOfMem;
29406  invmove->x = move->x;
29407  invmove->y = move->y;
29408  invmove->next = invmoves;
29409  invmoves = invmove;
29410  if (move->flags == CUDD_SWAP_MOVE) {
29411  invmove->flags = CUDD_SWAP_MOVE;
29412  size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y);
29413  if (!size) goto cuddZddUndoMovesOutOfMem;
29414  } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) {
29416  size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y);
29417  if (!size) goto cuddZddUndoMovesOutOfMem;
29418  size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y);
29419  if (!size) goto cuddZddUndoMovesOutOfMem;
29420  } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */
29421 #ifdef DD_DEBUG
29422  (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n");
29423 #endif
29424  invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE;
29425  size = cuddZddSwapInPlace(table,(int)move->x,(int)move->y);
29426  if (!size) goto cuddZddUndoMovesOutOfMem;
29427  size = cuddZddLinearInPlace(table,(int)move->x,(int)move->y);
29428  if (!size) goto cuddZddUndoMovesOutOfMem;
29429  }
29430  invmove->size = size;
29431  }
29432 
29433  return(invmoves);
29434 
29435  cuddZddUndoMovesOutOfMem:
29436  while (invmoves != NULL) {
29437  move = invmoves->next;
29438  cuddDeallocMove(table, invmoves);
29439  invmoves = move;
29440  }
29441  return((Move *) CUDD_OUT_OF_MEM);
29442 
29443 } /* end of cuddZddUndoMoves */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
FILE * err
Definition: cuddInt.h:424
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define CUDD_SWAP_MOVE
Definition: cuddInt.c:28542
static int cuddZddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:28728
#define CUDD_INVERSE_TRANSFORM_MOVE
Definition: cuddInt.c:28544
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddInt.c:28543
int size
Definition: cuddInt.h:473

◆ cuddZddUnion()

DdNode* cuddZddUnion ( DdManager zdd,
DdNode P,
DdNode Q 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddUnion.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 31404 of file cuddInt.c.

31408 {
31409  int p_top, q_top;
31410  DdNode *empty = DD_ZERO(zdd), *t, *e, *res;
31411  DdManager *table = zdd;
31412 
31413  statLine(zdd);
31414  if (P == empty)
31415  return(Q);
31416  if (Q == empty)
31417  return(P);
31418  if (P == Q)
31419  return(P);
31420 
31421  /* Check cache */
31422  res = cuddCacheLookup2Zdd(table, cuddZddUnion, P, Q);
31423  if (res != NULL)
31424  return(res);
31425 
31426  if (cuddIsConstant(P))
31427  p_top = P->index;
31428  else
31429  p_top = zdd->permZ[P->index];
31430  if (cuddIsConstant(Q))
31431  q_top = Q->index;
31432  else
31433  q_top = zdd->permZ[Q->index];
31434  if (p_top < q_top) {
31435  e = cuddZddUnion(zdd, cuddE(P), Q);
31436  if (e == NULL) return (NULL);
31437  cuddRef(e);
31438  res = cuddZddGetNode(zdd, P->index, cuddT(P), e);
31439  if (res == NULL) {
31440  Cudd_RecursiveDerefZdd(table, e);
31441  return(NULL);
31442  }
31443  cuddDeref(e);
31444  } else if (p_top > q_top) {
31445  e = cuddZddUnion(zdd, P, cuddE(Q));
31446  if (e == NULL) return(NULL);
31447  cuddRef(e);
31448  res = cuddZddGetNode(zdd, Q->index, cuddT(Q), e);
31449  if (res == NULL) {
31450  Cudd_RecursiveDerefZdd(table, e);
31451  return(NULL);
31452  }
31453  cuddDeref(e);
31454  } else {
31455  t = cuddZddUnion(zdd, cuddT(P), cuddT(Q));
31456  if (t == NULL) return(NULL);
31457  cuddRef(t);
31458  e = cuddZddUnion(zdd, cuddE(P), cuddE(Q));
31459  if (e == NULL) {
31460  Cudd_RecursiveDerefZdd(table, t);
31461  return(NULL);
31462  }
31463  cuddRef(e);
31464  res = cuddZddGetNode(zdd, P->index, t, e);
31465  if (res == NULL) {
31466  Cudd_RecursiveDerefZdd(table, t);
31467  Cudd_RecursiveDerefZdd(table, e);
31468  return(NULL);
31469  }
31470  cuddDeref(t);
31471  cuddDeref(e);
31472  }
31473 
31474  cuddCacheInsert2(table, cuddZddUnion, P, Q, res);
31475 
31476  return(res);
31477 
31478 } /* end of cuddZddUnion */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
static DdNode * empty
Definition: cuddInt.c:28567
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
#define cuddIsConstant(node)
Definition: cuddInt.h:593
DdNode * cuddZddUnion(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddInt.c:31404
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddInt.c:20408
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddUniqueCompare()

int cuddZddUniqueCompare ( int *  ptr_x,
int *  ptr_y 
)

Function********************************************************************

Synopsis [Comparison function used by qsort.]

Description [Comparison function used by qsort to order the variables according to the number of keys in the subtables. Returns the difference in number of keys between the two variables being compared.]

SideEffects [None]

SeeAlso []

Definition at line 29860 of file cuddInt.c.

29863 {
29864  return(zdd_entry[*ptr_y] - zdd_entry[*ptr_x]);
29865 
29866 } /* end of cuddZddUniqueCompare */
int * zdd_entry
Definition: cuddInt.c:29545

◆ cuddZddWeakDiv()

DdNode* cuddZddWeakDiv ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddWeakDiv.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddWeakDiv]

Definition at line 25528 of file cuddInt.c.

25532 {
25533  int v;
25534  DdNode *one = DD_ONE(dd);
25535  DdNode *zero = DD_ZERO(dd);
25536  DdNode *f0, *f1, *fd, *g0, *g1, *gd;
25537  DdNode *q, *tmp;
25538  DdNode *r;
25539  int flag;
25540 
25541  statLine(dd);
25542  if (g == one)
25543  return(f);
25544  if (f == zero || f == one)
25545  return(zero);
25546  if (f == g)
25547  return(one);
25548 
25549  /* Check cache. */
25550  r = cuddCacheLookup2Zdd(dd, cuddZddWeakDiv, f, g);
25551  if (r)
25552  return(r);
25553 
25554  v = g->index;
25555 
25556  flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
25557  if (flag == 1)
25558  return(NULL);
25559  Cudd_Ref(f1);
25560  Cudd_Ref(f0);
25561  Cudd_Ref(fd);
25562  flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd);
25563  if (flag == 1) {
25564  Cudd_RecursiveDerefZdd(dd, f1);
25565  Cudd_RecursiveDerefZdd(dd, f0);
25566  Cudd_RecursiveDerefZdd(dd, fd);
25567  return(NULL);
25568  }
25569  Cudd_Ref(g1);
25570  Cudd_Ref(g0);
25571  Cudd_Ref(gd);
25572 
25573  q = g;
25574 
25575  if (g0 != zero) {
25576  q = cuddZddWeakDiv(dd, f0, g0);
25577  if (q == NULL) {
25578  Cudd_RecursiveDerefZdd(dd, f1);
25579  Cudd_RecursiveDerefZdd(dd, f0);
25580  Cudd_RecursiveDerefZdd(dd, fd);
25581  Cudd_RecursiveDerefZdd(dd, g1);
25582  Cudd_RecursiveDerefZdd(dd, g0);
25583  Cudd_RecursiveDerefZdd(dd, gd);
25584  return(NULL);
25585  }
25586  Cudd_Ref(q);
25587  }
25588  else
25589  Cudd_Ref(q);
25590  Cudd_RecursiveDerefZdd(dd, f0);
25591  Cudd_RecursiveDerefZdd(dd, g0);
25592 
25593  if (q == zero) {
25594  Cudd_RecursiveDerefZdd(dd, f1);
25595  Cudd_RecursiveDerefZdd(dd, g1);
25596  Cudd_RecursiveDerefZdd(dd, fd);
25597  Cudd_RecursiveDerefZdd(dd, gd);
25598  cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero);
25599  Cudd_Deref(q);
25600  return(zero);
25601  }
25602 
25603  if (g1 != zero) {
25604  Cudd_RecursiveDerefZdd(dd, q);
25605  tmp = cuddZddWeakDiv(dd, f1, g1);
25606  if (tmp == NULL) {
25607  Cudd_RecursiveDerefZdd(dd, f1);
25608  Cudd_RecursiveDerefZdd(dd, g1);
25609  Cudd_RecursiveDerefZdd(dd, fd);
25610  Cudd_RecursiveDerefZdd(dd, gd);
25611  return(NULL);
25612  }
25613  Cudd_Ref(tmp);
25614  Cudd_RecursiveDerefZdd(dd, f1);
25615  Cudd_RecursiveDerefZdd(dd, g1);
25616  if (q == g)
25617  q = tmp;
25618  else {
25619  q = cuddZddIntersect(dd, q, tmp);
25620  if (q == NULL) {
25621  Cudd_RecursiveDerefZdd(dd, fd);
25622  Cudd_RecursiveDerefZdd(dd, gd);
25623  return(NULL);
25624  }
25625  Cudd_Ref(q);
25626  Cudd_RecursiveDerefZdd(dd, tmp);
25627  }
25628  }
25629  else {
25630  Cudd_RecursiveDerefZdd(dd, f1);
25631  Cudd_RecursiveDerefZdd(dd, g1);
25632  }
25633 
25634  if (q == zero) {
25635  Cudd_RecursiveDerefZdd(dd, fd);
25636  Cudd_RecursiveDerefZdd(dd, gd);
25637  cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, zero);
25638  Cudd_Deref(q);
25639  return(zero);
25640  }
25641 
25642  if (gd != zero) {
25643  Cudd_RecursiveDerefZdd(dd, q);
25644  tmp = cuddZddWeakDiv(dd, fd, gd);
25645  if (tmp == NULL) {
25646  Cudd_RecursiveDerefZdd(dd, fd);
25647  Cudd_RecursiveDerefZdd(dd, gd);
25648  return(NULL);
25649  }
25650  Cudd_Ref(tmp);
25651  Cudd_RecursiveDerefZdd(dd, fd);
25652  Cudd_RecursiveDerefZdd(dd, gd);
25653  if (q == g)
25654  q = tmp;
25655  else {
25656  q = cuddZddIntersect(dd, q, tmp);
25657  if (q == NULL) {
25658  Cudd_RecursiveDerefZdd(dd, tmp);
25659  return(NULL);
25660  }
25661  Cudd_Ref(q);
25662  Cudd_RecursiveDerefZdd(dd, tmp);
25663  }
25664  }
25665  else {
25666  Cudd_RecursiveDerefZdd(dd, fd);
25667  Cudd_RecursiveDerefZdd(dd, gd);
25668  }
25669 
25670  cuddCacheInsert2(dd, cuddZddWeakDiv, f, g, q);
25671  Cudd_Deref(q);
25672  return(q);
25673 
25674 } /* end of cuddZddWeakDiv */
Definition: cudd.h:264
static DdNode * one
Definition: cuddInt.c:16562
int cuddZddGetCofactors3(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)
Definition: cuddInt.c:26127
DdNode * cuddZddWeakDiv(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:25528
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
void Cudd_Ref(DdNode *n)
Definition: cuddInt.c:14002
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddInt.c:31493
DdHalfWord index
Definition: cudd.h:265
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void Cudd_Deref(DdNode *node)
Definition: cuddInt.c:14198
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ cuddZddWeakDivF()

DdNode* cuddZddWeakDivF ( DdManager dd,
DdNode f,
DdNode g 
)

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddWeakDivF.]

Description []

SideEffects [None]

SeeAlso [Cudd_zddWeakDivF]

Definition at line 25689 of file cuddInt.c.

25693 {
25694  int v, top_f, top_g, vf, vg;
25695  DdNode *one = DD_ONE(dd);
25696  DdNode *zero = DD_ZERO(dd);
25697  DdNode *f0, *f1, *fd, *g0, *g1, *gd;
25698  DdNode *q, *tmp;
25699  DdNode *r;
25700  DdNode *term1, *term0, *termd;
25701  int flag;
25702  int pv, nv;
25703 
25704  statLine(dd);
25705  if (g == one)
25706  return(f);
25707  if (f == zero || f == one)
25708  return(zero);
25709  if (f == g)
25710  return(one);
25711 
25712  /* Check cache. */
25713  r = cuddCacheLookup2Zdd(dd, cuddZddWeakDivF, f, g);
25714  if (r)
25715  return(r);
25716 
25717  top_f = dd->permZ[f->index];
25718  top_g = dd->permZ[g->index];
25719  vf = top_f >> 1;
25720  vg = top_g >> 1;
25721  v = ddMin(top_f, top_g);
25722 
25723  if (v == top_f && vf < vg) {
25724  v = f->index;
25725  flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
25726  if (flag == 1)
25727  return(NULL);
25728  Cudd_Ref(f1);
25729  Cudd_Ref(f0);
25730  Cudd_Ref(fd);
25731 
25732  pv = cuddZddGetPosVarIndex(dd, v);
25733  nv = cuddZddGetNegVarIndex(dd, v);
25734 
25735  term1 = cuddZddWeakDivF(dd, f1, g);
25736  if (term1 == NULL) {
25737  Cudd_RecursiveDerefZdd(dd, f1);
25738  Cudd_RecursiveDerefZdd(dd, f0);
25739  Cudd_RecursiveDerefZdd(dd, fd);
25740  return(NULL);
25741  }
25742  Cudd_Ref(term1);
25743  Cudd_RecursiveDerefZdd(dd, f1);
25744  term0 = cuddZddWeakDivF(dd, f0, g);
25745  if (term0 == NULL) {
25746  Cudd_RecursiveDerefZdd(dd, f0);
25747  Cudd_RecursiveDerefZdd(dd, fd);
25748  Cudd_RecursiveDerefZdd(dd, term1);
25749  return(NULL);
25750  }
25751  Cudd_Ref(term0);
25752  Cudd_RecursiveDerefZdd(dd, f0);
25753  termd = cuddZddWeakDivF(dd, fd, g);
25754  if (termd == NULL) {
25755  Cudd_RecursiveDerefZdd(dd, fd);
25756  Cudd_RecursiveDerefZdd(dd, term1);
25757  Cudd_RecursiveDerefZdd(dd, term0);
25758  return(NULL);
25759  }
25760  Cudd_Ref(termd);
25761  Cudd_RecursiveDerefZdd(dd, fd);
25762 
25763  tmp = cuddZddGetNode(dd, nv, term0, termd); /* nv = zi */
25764  if (tmp == NULL) {
25765  Cudd_RecursiveDerefZdd(dd, term1);
25766  Cudd_RecursiveDerefZdd(dd, term0);
25767  Cudd_RecursiveDerefZdd(dd, termd);
25768  return(NULL);
25769  }
25770  Cudd_Ref(tmp);
25771  Cudd_RecursiveDerefZdd(dd, term0);
25772  Cudd_RecursiveDerefZdd(dd, termd);
25773  q = cuddZddGetNode(dd, pv, term1, tmp); /* pv = yi */
25774  if (q == NULL) {
25775  Cudd_RecursiveDerefZdd(dd, term1);
25776  Cudd_RecursiveDerefZdd(dd, tmp);
25777  return(NULL);
25778  }
25779  Cudd_Ref(q);
25780  Cudd_RecursiveDerefZdd(dd, term1);
25781  Cudd_RecursiveDerefZdd(dd, tmp);
25782 
25783  cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q);
25784  Cudd_Deref(q);
25785  return(q);
25786  }
25787 
25788  if (v == top_f)
25789  v = f->index;
25790  else
25791  v = g->index;
25792 
25793  flag = cuddZddGetCofactors3(dd, f, v, &f1, &f0, &fd);
25794  if (flag == 1)
25795  return(NULL);
25796  Cudd_Ref(f1);
25797  Cudd_Ref(f0);
25798  Cudd_Ref(fd);
25799  flag = cuddZddGetCofactors3(dd, g, v, &g1, &g0, &gd);
25800  if (flag == 1) {
25801  Cudd_RecursiveDerefZdd(dd, f1);
25802  Cudd_RecursiveDerefZdd(dd, f0);
25803  Cudd_RecursiveDerefZdd(dd, fd);
25804  return(NULL);
25805  }
25806  Cudd_Ref(g1);
25807  Cudd_Ref(g0);
25808  Cudd_Ref(gd);
25809 
25810  q = g;
25811 
25812  if (g0 != zero) {
25813  q = cuddZddWeakDivF(dd, f0, g0);
25814  if (q == NULL) {
25815  Cudd_RecursiveDerefZdd(dd, f1);
25816  Cudd_RecursiveDerefZdd(dd, f0);
25817  Cudd_RecursiveDerefZdd(dd, fd);
25818  Cudd_RecursiveDerefZdd(dd, g1);
25819  Cudd_RecursiveDerefZdd(dd, g0);
25820  Cudd_RecursiveDerefZdd(dd, gd);
25821  return(NULL);
25822  }
25823  Cudd_Ref(q);
25824  }
25825  else
25826  Cudd_Ref(q);
25827  Cudd_RecursiveDerefZdd(dd, f0);
25828  Cudd_RecursiveDerefZdd(dd, g0);
25829 
25830  if (q == zero) {
25831  Cudd_RecursiveDerefZdd(dd, f1);
25832  Cudd_RecursiveDerefZdd(dd, g1);
25833  Cudd_RecursiveDerefZdd(dd, fd);
25834  Cudd_RecursiveDerefZdd(dd, gd);
25835  cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero);
25836  Cudd_Deref(q);
25837  return(zero);
25838  }
25839 
25840  if (g1 != zero) {
25841  Cudd_RecursiveDerefZdd(dd, q);
25842  tmp = cuddZddWeakDivF(dd, f1, g1);
25843  if (tmp == NULL) {
25844  Cudd_RecursiveDerefZdd(dd, f1);
25845  Cudd_RecursiveDerefZdd(dd, g1);
25846  Cudd_RecursiveDerefZdd(dd, fd);
25847  Cudd_RecursiveDerefZdd(dd, gd);
25848  return(NULL);
25849  }
25850  Cudd_Ref(tmp);
25851  Cudd_RecursiveDerefZdd(dd, f1);
25852  Cudd_RecursiveDerefZdd(dd, g1);
25853  if (q == g)
25854  q = tmp;
25855  else {
25856  q = cuddZddIntersect(dd, q, tmp);
25857  if (q == NULL) {
25858  Cudd_RecursiveDerefZdd(dd, fd);
25859  Cudd_RecursiveDerefZdd(dd, gd);
25860  return(NULL);
25861  }
25862  Cudd_Ref(q);
25863  Cudd_RecursiveDerefZdd(dd, tmp);
25864  }
25865  }
25866  else {
25867  Cudd_RecursiveDerefZdd(dd, f1);
25868  Cudd_RecursiveDerefZdd(dd, g1);
25869  }
25870 
25871  if (q == zero) {
25872  Cudd_RecursiveDerefZdd(dd, fd);
25873  Cudd_RecursiveDerefZdd(dd, gd);
25874  cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, zero);
25875  Cudd_Deref(q);
25876  return(zero);
25877  }
25878 
25879  if (gd != zero) {
25880  Cudd_RecursiveDerefZdd(dd, q);
25881  tmp = cuddZddWeakDivF(dd, fd, gd);
25882  if (tmp == NULL) {
25883  Cudd_RecursiveDerefZdd(dd, fd);
25884  Cudd_RecursiveDerefZdd(dd, gd);
25885  return(NULL);
25886  }
25887  Cudd_Ref(tmp);
25888  Cudd_RecursiveDerefZdd(dd, fd);
25889  Cudd_RecursiveDerefZdd(dd, gd);
25890  if (q == g)
25891  q = tmp;
25892  else {
25893  q = cuddZddIntersect(dd, q, tmp);
25894  if (q == NULL) {
25895  Cudd_RecursiveDerefZdd(dd, tmp);
25896  return(NULL);
25897  }
25898  Cudd_Ref(q);
25899  Cudd_RecursiveDerefZdd(dd, tmp);
25900  }
25901  }
25902  else {
25903  Cudd_RecursiveDerefZdd(dd, fd);
25904  Cudd_RecursiveDerefZdd(dd, gd);
25905  }
25906 
25907  cuddCacheInsert2(dd, cuddZddWeakDivF, f, g, q);
25908  Cudd_Deref(q);
25909  return(q);
25910 
25911 } /* end of cuddZddWeakDivF */
Definition: cudd.h:264
static DdNode * one
Definition: cuddInt.c:16562
int cuddZddGetCofactors3(DdManager *dd, DdNode *f, int v, DdNode **f1, DdNode **f0, DdNode **fd)
Definition: cuddInt.c:26127
int cuddZddGetPosVarIndex(DdManager *dd, int index)
Definition: cuddInt.c:26332
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
void Cudd_Ref(DdNode *n)
Definition: cuddInt.c:14002
#define ddMin(x, y)
Definition: cuddInt.h:771
DdNode * cuddZddIntersect(DdManager *zdd, DdNode *P, DdNode *Q)
Definition: cuddInt.c:31493
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddInt.c:20408
DdHalfWord index
Definition: cudd.h:265
DdNode * cuddZddWeakDivF(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddInt.c:25689
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void Cudd_Deref(DdNode *node)
Definition: cuddInt.c:14198
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
int cuddZddGetNegVarIndex(DdManager *dd, int index)
Definition: cuddInt.c:26353
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ ddBddMaximallyExpand()

static DdNode * ddBddMaximallyExpand ( DdManager dd,
DdNode lb,
DdNode ub,
DdNode f 
)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_bddMaximallyExpand.]

Description [Performs the recursive step of Cudd_bddMaximallyExpand. Returns set of primes or zero BDD if successful; NULL otherwise. On entry to this function, ub and lb should be different from the zero BDD. The function then maintains this invariant.]

SideEffects [None]

SeeAlso []

There are three major terminal cases in theory: ub -> f : return ub lb == f : return lb not(lb -> f): return zero Only the second case can be checked exactly in constant time. For the others, we check for sufficient conditions.

Definition at line 17521 of file cuddInt.c.

17526  {
17527  DdNode *one, *zero, *lbv, *lbvn, *lbnx, *ubv, *ubvn, *fv, *fvn, *res;
17528  DdNode *F, *UB, *LB, *t, *e;
17529  unsigned int top, toplb, topub, topf, index;
17530 
17531  statLine(dd);
17532  /* Terminal cases. */
17533  one = DD_ONE(dd);
17534  zero = Cudd_Not(one);
17535  assert(ub != zero && lb != zero);
17543  if (ub == f || f == one) return(ub);
17544  if (lb == f) return(lb);
17545  if (f == zero || ub == Cudd_Not(f) || lb == one || lb == Cudd_Not(f))
17546  return(zero);
17547  if (!Cudd_IsComplement(lb) && Cudd_IsComplement(f)) return(zero);
17548 
17549  /* Here lb and f are not constant. */
17550 
17551  /* Check cache. Since lb and ub are cubes, their local reference counts
17552  ** are always 1. Hence, we only check the reference count of f.
17553  */
17554  F = Cudd_Regular(f);
17555  if (F->ref != 1) {
17556  DdNode *tmp = cuddCacheLookup(dd, DD_BDD_MAX_EXP_TAG, lb, ub, f);
17557  if (tmp != NULL) {
17558  return(tmp);
17559  }
17560  }
17561 
17562  /* Compute cofactors. For lb we use the non-zero one in
17563  ** both branches of the recursion.
17564  */
17565  LB = Cudd_Regular(lb);
17566  UB = Cudd_Regular(ub);
17567  topf = dd->perm[F->index];
17568  toplb = dd->perm[LB->index];
17569  topub = (ub == one) ? CUDD_CONST_INDEX : dd->perm[UB->index];
17570  assert(toplb <= topub);
17571  top = ddMin(topf,toplb);
17572  if (toplb == top) {
17573  index = LB->index;
17574  lbv = cuddT(LB);
17575  lbvn = cuddE(LB);
17576  if (lb != LB) {
17577  lbv = Cudd_Not(lbv);
17578  lbvn = Cudd_Not(lbvn);
17579  }
17580  if (lbv == zero) {
17581  lbnx = lbvn;
17582  } else {
17583  lbnx = lbv;
17584  }
17585  } else {
17586  index = F->index;
17587  lbnx = lbv = lbvn = lb;
17588  }
17589  if (topub == top) {
17590  ubv = cuddT(UB);
17591  ubvn = cuddE(UB);
17592  if (ub != UB) {
17593  ubv = Cudd_Not(ubv);
17594  ubvn = Cudd_Not(ubvn);
17595  }
17596  } else {
17597  ubv = ubvn = ub;
17598  }
17599  if (topf == top) {
17600  fv = cuddT(F);
17601  fvn = cuddE(F);
17602  if (f != F) {
17603  fv = Cudd_Not(fv);
17604  fvn = Cudd_Not(fvn);
17605  }
17606  } else {
17607  fv = fvn = f;
17608  }
17609 
17610  /* Recursive calls. */
17611  if (ubv != zero) {
17612  t = ddBddMaximallyExpand(dd, lbnx, ubv, fv);
17613  if (t == NULL) return(NULL);
17614  } else {
17615  assert(topub == toplb && topub == top && lbv == zero);
17616  t = zero;
17617  }
17618  cuddRef(t);
17619 
17620  /* If the top variable appears only in lb, the positive and negative
17621  ** cofactors of each operand are the same. We want to avoid a
17622  ** needless recursive call, which would force us to give up the
17623  ** cache optimization trick based on reference counts.
17624  */
17625  if (ubv == ubvn && fv == fvn) {
17626  res = t;
17627  } else {
17628  if (ubvn != zero) {
17629  e = ddBddMaximallyExpand(dd, lbnx, ubvn, fvn);
17630  if (e == NULL) {
17631  Cudd_IterDerefBdd(dd,t);
17632  return(NULL);
17633  }
17634  } else {
17635  assert(topub == toplb && topub == top && lbvn == zero);
17636  e = zero;
17637  }
17638 
17639  if (t == e) {
17640  res = t;
17641  } else {
17642  cuddRef(e);
17643 
17644  if (toplb == top) {
17645  if (lbv == zero) {
17646  /* Top variable appears in negative phase. */
17647  if (t != one) {
17648  DdNode *newT;
17649  if (Cudd_IsComplement(t)) {
17650  newT = cuddUniqueInter(dd, index, Cudd_Not(t), zero);
17651  if (newT == NULL) {
17652  Cudd_IterDerefBdd(dd,t);
17653  Cudd_IterDerefBdd(dd,e);
17654  return(NULL);
17655  }
17656  newT = Cudd_Not(newT);
17657  } else {
17658  newT = cuddUniqueInter(dd, index, t, one);
17659  if (newT == NULL) {
17660  Cudd_IterDerefBdd(dd,t);
17661  Cudd_IterDerefBdd(dd,e);
17662  return(NULL);
17663  }
17664  }
17665  cuddRef(newT);
17666  cuddDeref(t);
17667  t = newT;
17668  }
17669  } else if (lbvn == zero) {
17670  /* Top variable appears in positive phase. */
17671  if (e != one) {
17672  DdNode *newE;
17673  newE = cuddUniqueInter(dd, index, one, e);
17674  if (newE == NULL) {
17675  Cudd_IterDerefBdd(dd,t);
17676  Cudd_IterDerefBdd(dd,e);
17677  return(NULL);
17678  }
17679  cuddRef(newE);
17680  cuddDeref(e);
17681  e = newE;
17682  }
17683  } else {
17684  /* Not a cube. */
17685  Cudd_IterDerefBdd(dd,t);
17686  Cudd_IterDerefBdd(dd,e);
17687  return(NULL);
17688  }
17689  }
17690 
17691  /* Combine results. */
17692  res = cuddBddAndRecur(dd, t, e);
17693  if (res == NULL) {
17694  Cudd_IterDerefBdd(dd,t);
17695  Cudd_IterDerefBdd(dd,e);
17696  return(NULL);
17697  }
17698  cuddRef(res);
17699  Cudd_IterDerefBdd(dd,t);
17700  Cudd_IterDerefBdd(dd,e);
17701  }
17702  }
17703 
17704  /* Cache result and return. */
17705  if (F->ref != 1) {
17706  cuddCacheInsert(dd, DD_BDD_MAX_EXP_TAG, lb, ub, f, res);
17707  }
17708  cuddDeref(res);
17709  return(res);
17710 
17711  } /* end of ddBddMaximallyExpand */
DdHalfWord ref
Definition: cudd.h:266
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
DdNode * cuddCacheLookup(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddInt.c:4413
#define assert(ex)
Definition: util.h:141
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
#define DD_BDD_MAX_EXP_TAG
Definition: cuddInt.h:191
#define statLine(dd)
Definition: cuddInt.h:990
#define Cudd_IsComplement(node)
Definition: cudd.h:401
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14090
#define CUDD_CONST_INDEX
Definition: cudd.h:107
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
void cuddCacheInsert(DdManager *table, ptruint op, DdNode *f, DdNode *g, DdNode *h, DdNode *data)
Definition: cuddInt.c:4283
DdHalfWord index
Definition: cudd.h:265
static DdNode * ddBddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f)
Definition: cuddInt.c:17521
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633
int * perm
Definition: cuddInt.h:369

◆ ddBddShortestPathUnate()

static int ddBddShortestPathUnate ( DdManager dd,
DdNode f,
int *  phases,
st_table table 
)
static

Function********************************************************************

Synopsis [Performs shortest path computation on a unate function.]

Description [Performs shortest path computation on a unate function. Returns the length of the shortest path to one if successful; CUDD_OUT_OF_MEM otherwise. This function is based on the observation that in the BDD of a unate function no node except the constant is reachable from the root via paths of different parity.]

SideEffects [None]

SeeAlso [getShortest]

Definition at line 17730 of file cuddInt.c.

17735  {
17736  int positive, l, lT, lE;
17737  DdNode *one = DD_ONE(dd);
17738  DdNode *zero = Cudd_Not(one);
17739  DdNode *F, *fv, *fvn;
17740 
17741  if (st_lookup_int(table, f, &l)) {
17742  return(l);
17743  }
17744  if (f == one) {
17745  l = 0;
17746  } else if (f == zero) {
17747  l = DD_BIGGY;
17748  } else {
17749  F = Cudd_Regular(f);
17750  fv = cuddT(F);
17751  fvn = cuddE(F);
17752  if (f != F) {
17753  fv = Cudd_Not(fv);
17754  fvn = Cudd_Not(fvn);
17755  }
17756  lT = ddBddShortestPathUnate(dd, fv, phases, table);
17757  lE = ddBddShortestPathUnate(dd, fvn, phases, table);
17758  positive = phases[F->index];
17759  l = positive ? ddMin(lT+1, lE) : ddMin(lT, lE+1);
17760  }
17761  if (st_insert(table, f, (void *)(ptrint) l) == ST_OUT_OF_MEM) {
17762  return(CUDD_OUT_OF_MEM);
17763  }
17764  return(l);
17765 
17766  } /* end of ddShortestPathUnate */
int ptrint
Definition: cuddInt.h:249
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
int st_lookup_int(st_table *, void *, int *)
Definition: st.c:307
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
int st_insert(st_table *, void *, void *)
Definition: st.c:343
#define ddMin(x, y)
Definition: cuddInt.h:771
static int ddBddShortestPathUnate(DdManager *dd, DdNode *f, int *phases, st_table *table)
Definition: cuddInt.c:17730
#define cuddT(node)
Definition: cuddInt.h:609
#define DD_BIGGY
Definition: cuddInt.c:16539
#define ST_OUT_OF_MEM
Definition: st.h:41
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ ddCheckPermuation()

static int ddCheckPermuation ( DdManager table,
MtrNode treenode,
int *  perm,
int *  invperm 
)
static

Function********************************************************************

Synopsis [Checks the BDD variable group tree before a shuffle.]

Description [Checks the BDD variable group tree before a shuffle. Returns 1 if successful; 0 otherwise.]

SideEffects [Changes the BDD variable group tree.]

SeeAlso []

Definition at line 16424 of file cuddInt.c.

16429 {
16430  unsigned int i, size;
16431  int index, level, minLevel, maxLevel;
16432 
16433  if (treenode == NULL) return(1);
16434 
16435  minLevel = table->size;
16436  maxLevel = 0;
16437  /* i : level */
16438  for (i = treenode->low; i < treenode->low + treenode->size; i++) {
16439  index = table->invperm[i];
16440  level = perm[index];
16441  if (level < minLevel)
16442  minLevel = level;
16443  if (level > maxLevel)
16444  maxLevel = level;
16445  }
16446  size = maxLevel - minLevel + 1;
16447  if (size != treenode->size)
16448  return(0);
16449 
16450  if (treenode->child != NULL) {
16451  if (!ddCheckPermuation(table, treenode->child, perm, invperm))
16452  return(0);
16453  }
16454  if (treenode->younger != NULL) {
16455  if (!ddCheckPermuation(table, treenode->younger, perm, invperm))
16456  return(0);
16457  }
16458  return(1);
16459 }
MtrHalfWord size
Definition: mtr.h:129
int size
Definition: cuddInt.h:345
static int ddCheckPermuation(DdManager *table, MtrNode *treenode, int *perm, int *invperm)
Definition: cuddInt.c:16424
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord low
Definition: mtr.h:128
int * invperm
Definition: cuddInt.h:371
struct MtrNode * child
Definition: mtr.h:132

◆ ddClearFlag()

static void ddClearFlag ( DdNode f)
static

Function********************************************************************

Synopsis [Performs a DFS from f, clearing the LSB of the next pointers.]

Description []

SideEffects [None]

SeeAlso [ddSupportStep ddFindSupport ddLeavesInt ddDagInt]

Definition at line 23821 of file cuddInt.c.

23823 {
23824 if (!Cudd_IsComplement(f->next)) {
23825 return;
23826 }
23827 /* Clear visited flag. */
23828 f->next = Cudd_Regular(f->next);
23829 if (cuddIsConstant(f)) {
23830 return;
23831 }
23832 ddClearFlag(cuddT(f));
23834 return;
23835 
23836 } /* end of ddClearFlag */
#define Cudd_Regular(node)
Definition: cudd.h:373
static void ddClearFlag(DdNode *f)
Definition: cuddInt.c:23821
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode * next
Definition: cudd.h:267
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddE(node)
Definition: cuddInt.h:625

◆ ddClearGlobal()

static void ddClearGlobal ( DdManager table,
int  lower,
int  maxlevel 
)
static

Function********************************************************************

Synopsis [Scans the DD and clears the LSB of the next pointers.]

Description [Scans the DD and clears the LSB of the next pointers. The LSB of the next pointers are used as markers to tell whether a node was reached. Once the roots are counted, these flags are reset.]

SideEffects [None]

SeeAlso [ddCountRoots]

Definition at line 7088 of file cuddInt.c.

7092 {
7093  int i,j;
7094  DdNode *f;
7095  DdNodePtr *nodelist;
7096  DdNode *sentinel = &(table->sentinel);
7097  int slots;
7098 
7099  for (i = lower; i <= maxlevel; i++) {
7100  nodelist = table->subtables[i].nodelist;
7101  slots = table->subtables[i].slots;
7102  for (j = 0; j < slots; j++) {
7103  f = nodelist[j];
7104  while (f != sentinel) {
7105  f->next = Cudd_Regular(f->next);
7106  f = f->next;
7107  }
7108  }
7109  }
7110 
7111 } /* end of ddClearGlobal */
Definition: cudd.h:264
#define Cudd_Regular(node)
Definition: cudd.h:373
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode sentinel
Definition: cuddInt.h:328
DdNode * next
Definition: cudd.h:267
DdNode ** nodelist
Definition: cuddInt.h:311
unsigned int slots
Definition: cuddInt.h:313

◆ ddClearGlobal2()

static void ddClearGlobal2 ( DdManager table)
static

Function********************************************************************

Synopsis [Scans the DD and clears the LSB of the next pointers.]

Description [The LSB of the next pointers are used as markers to tell whether a node was reached by at least one DFS. Once the interaction matrix is built, these flags are reset.]

SideEffects [None]

SeeAlso []

Definition at line 11139 of file cuddInt.c.

11141 {
11142  int i,j;
11143  DdNode *f;
11144  DdNode *sentinel = &(table->sentinel);
11145  DdNodePtr *nodelist;
11146  int slots;
11147 
11148  for (i = 0; i < table->size; i++) {
11149  nodelist = table->subtables[i].nodelist;
11150  slots = table->subtables[i].slots;
11151  for (j = 0; j < slots; j++) {
11152  f = nodelist[j];
11153  while (f != sentinel) {
11154  f->next = Cudd_Regular(f->next);
11155  f = f->next;
11156  }
11157  }
11158  }
11159 
11160 } /* end of ddClearGlobal */
Definition: cudd.h:264
int size
Definition: cuddInt.h:345
#define Cudd_Regular(node)
Definition: cudd.h:373
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode sentinel
Definition: cuddInt.h:328
DdNode * next
Definition: cudd.h:267
DdNode ** nodelist
Definition: cuddInt.h:311
unsigned int slots
Definition: cuddInt.h:313

◆ ddClearLocal()

static void ddClearLocal ( DdNode f)
static

Function********************************************************************

Synopsis [Performs a DFS from f, clearing the LSB of the then pointers.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 11074 of file cuddInt.c.

11076 {
11077  if (cuddIsConstant(f) || !Cudd_IsComplement(cuddT(f))) {
11078  return;
11079  }
11080  /* clear visited flag */
11081  cuddT(f) = Cudd_Regular(cuddT(f));
11082  ddClearLocal(cuddT(f));
11084  return;
11085 
11086 } /* end of ddClearLocal */
#define Cudd_Regular(node)
Definition: cudd.h:373
static void ddClearLocal(DdNode *f)
Definition: cuddInt.c:11074
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddE(node)
Definition: cuddInt.h:625

◆ ddCountMintermAux()

static double ddCountMintermAux ( DdNode node,
double  max,
DdHashTable table 
)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_CountMinterm.]

Description [Performs the recursive step of Cudd_CountMinterm. It is based on the following identity. Let |f| be the number of minterms of f. Then: <xmp> |f| = (|f0|+|f1|)/2 </xmp> where f0 and f1 are the two cofactors of f. Does not use the identity |f'| = max - |f|, to minimize loss of accuracy due to roundoff. Returns the number of minterms of the function rooted at node.]

SideEffects [None]

Definition at line 23527 of file cuddInt.c.

23531 {
23532 DdNode *N, *Nt, *Ne;
23533 double min, minT, minE;
23534 DdNode *res;
23535 
23536 N = Cudd_Regular(node);
23537 
23538 if (cuddIsConstant(N)) {
23539 if (node == background || node == zero) {
23540 return(0.0);
23541 } else {
23542 return(max);
23543 }
23544 }
23545 if (N->ref != 1 && (res = cuddHashTableLookup1(table,node)) != NULL) {
23546 min = cuddV(res);
23547 if (res->ref == 0) {
23548 table->manager->dead++;
23549 table->manager->constants.dead++;
23550 }
23551 return(min);
23552 }
23553 
23554 Nt = cuddT(N); Ne = cuddE(N);
23555 if (Cudd_IsComplement(node)) {
23556 Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne);
23557 }
23558 
23559 minT = ddCountMintermAux(Nt,max,table);
23560 if (minT == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
23561 minT *= 0.5;
23562 minE = ddCountMintermAux(Ne,max,table);
23563 if (minE == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
23564 minE *= 0.5;
23565 min = minT + minE;
23566 
23567 if (N->ref != 1) {
23568 ptrint fanout = (ptrint) N->ref;
23569 cuddSatDec(fanout);
23570 res = cuddUniqueConst(table->manager,min);
23571 if (!cuddHashTableInsert1(table,node,res,fanout)) {
23572 cuddRef(res); Cudd_RecursiveDeref(table->manager, res);
23573 return((double)CUDD_OUT_OF_MEM);
23574 }
23575 }
23576 
23577 return(min);
23578 
23579 } /* end of ddCountMintermAux */
DdHalfWord ref
Definition: cudd.h:266
#define cuddRef(n)
Definition: cuddInt.h:557
int ptrint
Definition: cuddInt.h:249
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static double ddCountMintermAux(DdNode *node, double max, DdHashTable *table)
Definition: cuddInt.c:23527
int cuddHashTableInsert1(DdHashTable *hash, DdNode *f, DdNode *value, ptrint count)
Definition: cuddInt.c:11803
DdManager * manager
Definition: cuddInt.h:298
DdNode * cuddUniqueConst(DdManager *unique, CUDD_VALUE_TYPE value)
Definition: cuddInt.c:20837
#define Cudd_Regular(node)
Definition: cudd.h:373
static DdNode * background
Definition: cuddInt.c:22141
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
#define cuddV(node)
Definition: cuddInt.h:641
unsigned int dead
Definition: cuddInt.h:355
#define Cudd_IsComplement(node)
Definition: cudd.h:401
unsigned int dead
Definition: cuddInt.h:316
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddE(node)
Definition: cuddInt.h:625
#define cuddSatDec(x)
Definition: cuddInt.h:849
static DdNode * zero
Definition: cuddInt.c:16562
DdSubtable constants
Definition: cuddInt.h:351
DdNode * cuddHashTableLookup1(DdHashTable *hash, DdNode *f)
Definition: cuddInt.c:11855

◆ ddCountPathAux()

static double ddCountPathAux ( DdNode node,
st_table table 
)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_CountPath.]

Description [Performs the recursive step of Cudd_CountPath. It is based on the following identity. Let |f| be the number of paths of f. Then: <xmp> |f| = |f0|+|f1| </xmp> where f0 and f1 are the two cofactors of f. Uses the identity |f'| = |f|, to improve the utilization of the (local) cache. Returns the number of paths of the function rooted at node.]

SideEffects [None]

Definition at line 23600 of file cuddInt.c.

23603 {
23604 
23605 DdNode *Nv, *Nnv;
23606 double paths, *ppaths, paths1, paths2;
23607 double *dummy;
23608 
23609 
23610 if (cuddIsConstant(node)) {
23611 return(1.0);
23612 }
23613 if (st_lookup(table, node, &dummy)) {
23614 paths = *dummy;
23615 return(paths);
23616 }
23617 
23618 Nv = cuddT(node); Nnv = cuddE(node);
23619 
23620 paths1 = ddCountPathAux(Nv,table);
23621 if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
23622 paths2 = ddCountPathAux(Cudd_Regular(Nnv),table);
23623 if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
23624 paths = paths1 + paths2;
23625 
23626 ppaths = ALLOC(double,1);
23627 if (ppaths == NULL) {
23628 return((double)CUDD_OUT_OF_MEM);
23629 }
23630 
23631 *ppaths = paths;
23632 
23633 if (st_add_direct(table,(char *)node, (char *)ppaths) == ST_OUT_OF_MEM) {
23634 FREE(ppaths);
23635 return((double)CUDD_OUT_OF_MEM);
23636 }
23637 return(paths);
23638 
23639 } /* end of ddCountPathAux */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
int st_lookup(st_table *, void *, void *)
Definition: st.c:271
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
#define Cudd_Regular(node)
Definition: cudd.h:373
#define ALLOC(type, num)
Definition: util.h:76
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define ST_OUT_OF_MEM
Definition: st.h:41
int st_add_direct(st_table *, void *, void *)
Definition: st.c:395
#define cuddE(node)
Definition: cuddInt.h:625
static double ddCountPathAux(DdNode *node, st_table *table)
Definition: cuddInt.c:23600

◆ ddCountPathsToNonZero()

static double ddCountPathsToNonZero ( DdNode N,
st_table table 
)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_CountPathsToNonZero.]

Description [Performs the recursive step of Cudd_CountPathsToNonZero. It is based on the following identity. Let |f| be the number of paths of f. Then: <xmp> |f| = |f0|+|f1| </xmp> where f0 and f1 are the two cofactors of f. Returns the number of paths of the function rooted at node.]

SideEffects [None]

Definition at line 23733 of file cuddInt.c.

23736 {
23737 
23738 DdNode *node, *Nt, *Ne;
23739 double paths, *ppaths, paths1, paths2;
23740 double *dummy;
23741 
23742 node = Cudd_Regular(N);
23743 if (cuddIsConstant(node)) {
23744 return((double) !(Cudd_IsComplement(N) || cuddV(node)==DD_ZERO_VAL));
23745 }
23746 if (st_lookup(table, N, &dummy)) {
23747 paths = *dummy;
23748 return(paths);
23749 }
23750 
23751 Nt = cuddT(node); Ne = cuddE(node);
23752 if (node != N) {
23753 Nt = Cudd_Not(Nt); Ne = Cudd_Not(Ne);
23754 }
23755 
23756 paths1 = ddCountPathsToNonZero(Nt,table);
23757 if (paths1 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
23758 paths2 = ddCountPathsToNonZero(Ne,table);
23759 if (paths2 == (double)CUDD_OUT_OF_MEM) return((double)CUDD_OUT_OF_MEM);
23760 paths = paths1 + paths2;
23761 
23762 ppaths = ALLOC(double,1);
23763 if (ppaths == NULL) {
23764 return((double)CUDD_OUT_OF_MEM);
23765 }
23766 
23767 *ppaths = paths;
23768 
23769 if (st_add_direct(table,(char *)N, (char *)ppaths) == ST_OUT_OF_MEM) {
23770 FREE(ppaths);
23771 return((double)CUDD_OUT_OF_MEM);
23772 }
23773 return(paths);
23774 
23775 } /* end of ddCountPathsToNonZero */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
int st_lookup(st_table *, void *, void *)
Definition: st.c:271
static double ddCountPathsToNonZero(DdNode *N, st_table *table)
Definition: cuddInt.c:23733
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define FREE(obj)
Definition: util.h:80
#define Cudd_Regular(node)
Definition: cudd.h:373
#define DD_ZERO_VAL
Definition: cuddInt.h:109
#define cuddV(node)
Definition: cuddInt.h:641
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define ALLOC(type, num)
Definition: util.h:76
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define ST_OUT_OF_MEM
Definition: st.h:41
int st_add_direct(st_table *, void *, void *)
Definition: st.c:395
#define cuddE(node)
Definition: cuddInt.h:625

◆ ddCountRoots()

static int ddCountRoots ( DdManager table,
int  lower,
int  upper 
)
static

Function********************************************************************

Synopsis [Counts the number of roots.]

Description [Counts the number of roots at the levels between lower and upper. The computation is based on breadth-first search. A node is a root if it is not reachable from any previously visited node. (All the nodes at level lower are therefore considered roots.) The visited flag uses the LSB of the next pointer. Returns the root count. The roots that are constant nodes are always ignored.]

SideEffects [None]

SeeAlso [ddClearGlobal]

Definition at line 7021 of file cuddInt.c.

7025 {
7026  int i,j;
7027  DdNode *f;
7028  DdNodePtr *nodelist;
7029  DdNode *sentinel = &(table->sentinel);
7030  int slots;
7031  int roots = 0;
7032  int maxlevel = lower;
7033 
7034  for (i = lower; i <= upper; i++) {
7035  nodelist = table->subtables[i].nodelist;
7036  slots = table->subtables[i].slots;
7037  for (j = 0; j < slots; j++) {
7038  f = nodelist[j];
7039  while (f != sentinel) {
7040  /* A node is a root of the DAG if it cannot be
7041  ** reached by nodes above it. If a node was never
7042  ** reached during the previous depth-first searches,
7043  ** then it is a root, and we start a new depth-first
7044  ** search from it.
7045  */
7046  if (!Cudd_IsComplement(f->next)) {
7047  if (f != table->vars[f->index]) {
7048  roots++;
7049  }
7050  }
7051  if (!Cudd_IsConstant(cuddT(f))) {
7052  cuddT(f)->next = Cudd_Complement(cuddT(f)->next);
7053  if (table->perm[cuddT(f)->index] > maxlevel)
7054  maxlevel = table->perm[cuddT(f)->index];
7055  }
7056  if (!Cudd_IsConstant(cuddE(f))) {
7057  Cudd_Regular(cuddE(f))->next =
7058  Cudd_Complement(Cudd_Regular(cuddE(f))->next);
7059  if (table->perm[Cudd_Regular(cuddE(f))->index] > maxlevel)
7060  maxlevel = table->perm[Cudd_Regular(cuddE(f))->index];
7061  }
7062  f = Cudd_Regular(f->next);
7063  }
7064  }
7065  }
7066  ddClearGlobal(table, lower, maxlevel);
7067 
7068  return(roots);
7069 
7070 } /* end of ddCountRoots */
Definition: cudd.h:264
#define Cudd_IsConstant(node)
Definition: cudd.h:328
#define Cudd_Regular(node)
Definition: cudd.h:373
DdSubtable * subtables
Definition: cuddInt.h:349
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode sentinel
Definition: cuddInt.h:328
DdNode * next
Definition: cudd.h:267
DdNode ** nodelist
Definition: cuddInt.h:311
#define Cudd_Complement(node)
Definition: cudd.h:387
#define cuddT(node)
Definition: cuddInt.h:609
static void ddClearGlobal(DdManager *table, int lower, int maxlevel)
Definition: cuddInt.c:7088
DdHalfWord index
Definition: cudd.h:265
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
int * perm
Definition: cuddInt.h:369

◆ ddCreateGroup()

static void ddCreateGroup ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [Creates a group encompassing variables from x to y in the DD table.]

Description [Creates a group encompassing variables from x to y in the DD table. In the current implementation it must be y == x+1. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 9156 of file cuddInt.c.

9160 {
9161  int gybot;
9162 
9163 #ifdef DD_DEBUG
9164  assert(y == x+1);
9165 #endif
9166 
9167  /* Find bottom of second group. */
9168  gybot = y;
9169  while ((unsigned) gybot < table->subtables[gybot].next)
9170  gybot = table->subtables[gybot].next;
9171 
9172  /* Link groups. */
9173  table->subtables[x].next = y;
9174  table->subtables[gybot].next = x;
9175 
9176  return;
9177 
9178 } /* ddCreateGroup */
#define assert(ex)
Definition: util.h:141
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int next
Definition: cuddInt.h:317

◆ ddDagInt()

static int ddDagInt ( DdNode n)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_DagSize.]

Description [Performs the recursive step of Cudd_DagSize. Returns the number of nodes in the graph rooted at n.]

SideEffects [None]

Definition at line 23253 of file cuddInt.c.

23255 {
23256 int tval, eval;
23257 
23258 if (Cudd_IsComplement(n->next)) {
23259 return(0);
23260 }
23261 n->next = Cudd_Not(n->next);
23262 if (cuddIsConstant(n)) {
23263 return(1);
23264 }
23265 tval = ddDagInt(cuddT(n));
23266 eval = ddDagInt(Cudd_Regular(cuddE(n)));
23267 return(1 + tval + eval);
23268 
23269 } /* end of ddDagInt */
static int ddDagInt(DdNode *n)
Definition: cuddInt.c:23253
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_Regular(node)
Definition: cudd.h:373
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode * next
Definition: cudd.h:267
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddE(node)
Definition: cuddInt.h:625

◆ ddDissolveGroup()

static void ddDissolveGroup ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [Dissolves a group in the DD table.]

Description [x and y are variables in a group to be cut in two. The cut is to pass between x and y.]

SideEffects [None]

Definition at line 10064 of file cuddInt.c.

10068 {
10069  int topx;
10070  int boty;
10071 
10072  /* find top and bottom of the two groups */
10073  boty = y;
10074  while ((unsigned) boty < table->subtables[boty].next)
10075  boty = table->subtables[boty].next;
10076 
10077  topx = table->subtables[boty].next;
10078 
10079  table->subtables[boty].next = y;
10080  table->subtables[x].next = topx;
10081 
10082  return;
10083 
10084 } /* end of ddDissolveGroup */
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int next
Definition: cuddInt.h:317

◆ ddEpdCountMintermAux()

static int ddEpdCountMintermAux ( DdNode node,
EpDouble max,
EpDouble epd,
st_table table 
)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_EpdCountMinterm.]

Description [Performs the recursive step of Cudd_EpdCountMinterm. It is based on the following identity. Let |f| be the number of minterms of f. Then: <xmp> |f| = (|f0|+|f1|)/2 </xmp> where f0 and f1 are the two cofactors of f. Does not use the identity |f'| = max - |f|, to minimize loss of accuracy due to roundoff. Returns the number of minterms of the function rooted at node.]

SideEffects [None]

Definition at line 23661 of file cuddInt.c.

23666 {
23667 DdNode *Nt, *Ne;
23668 EpDouble *min, minT, minE;
23669 EpDouble *res;
23670 int status;
23671 
23672 /* node is assumed to be regular */
23673 if (cuddIsConstant(node)) {
23674 if (node == background || node == zero) {
23675 EpdMakeZero(epd, 0);
23676 } else {
23677 EpdCopy(max, epd);
23678 }
23679 return(0);
23680 }
23681 if (node->ref != 1 && st_lookup(table, node, &res)) {
23682 EpdCopy(res, epd);
23683 return(0);
23684 }
23685 
23686 Nt = cuddT(node); Ne = cuddE(node);
23687 
23688 status = ddEpdCountMintermAux(Nt,max,&minT,table);
23689 if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM);
23690 EpdMultiply(&minT, (double)0.5);
23691 status = ddEpdCountMintermAux(Cudd_Regular(Ne),max,&minE,table);
23692 if (status == CUDD_OUT_OF_MEM) return(CUDD_OUT_OF_MEM);
23693 if (Cudd_IsComplement(Ne)) {
23694 EpdSubtract3(max, &minE, epd);
23695 EpdCopy(epd, &minE);
23696 }
23697 EpdMultiply(&minE, (double)0.5);
23698 EpdAdd3(&minT, &minE, epd);
23699 
23700 if (node->ref > 1) {
23701 min = EpdAlloc();
23702 if (!min)
23703 return(CUDD_OUT_OF_MEM);
23704 EpdCopy(epd, min);
23705 if (st_insert(table, (char *)node, (char *)min) == ST_OUT_OF_MEM) {
23706 EpdFree(min);
23707 return(CUDD_OUT_OF_MEM);
23708 }
23709 }
23710 
23711 return(0);
23712 
23713 } /* end of ddEpdCountMintermAux */
DdHalfWord ref
Definition: cudd.h:266
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
void EpdMultiply(EpDouble *epd1, double value)
Definition: epd.c:130
void EpdFree(EpDouble *epd)
Definition: epd.c:92
int st_lookup(st_table *, void *, void *)
Definition: st.c:271
Definition: cudd.h:264
#define Cudd_Regular(node)
Definition: cudd.h:373
static DdNode * background
Definition: cuddInt.c:22141
int st_insert(st_table *, void *, void *)
Definition: st.c:343
#define Cudd_IsComplement(node)
Definition: cudd.h:401
static int ddEpdCountMintermAux(DdNode *node, EpDouble *max, EpDouble *epd, st_table *table)
Definition: cuddInt.c:23661
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define ST_OUT_OF_MEM
Definition: st.h:41
void EpdAdd3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3)
Definition: epd.c:236
void EpdSubtract3(EpDouble *epd1, EpDouble *epd2, EpDouble *epd3)
Definition: epd.c:302
void EpdMakeZero(EpDouble *epd, int sign)
Definition: epd.c:555
EpDouble * EpdAlloc(void)
Definition: epd.c:71
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562
void EpdCopy(EpDouble *from, EpDouble *to)
Definition: epd.c:600

◆ ddExchange()

static int ddExchange ( DdManager table,
int  x,
int  y,
double  temp 
)
static

Function********************************************************************

Synopsis [This function is for exchanging two variables, x and y.]

Description [This is the same funcion as ddSwapping except for comparison expression. Use probability function, exp(-size_change/temp).]

SideEffects [None]

SeeAlso []

Definition at line 962 of file cuddInt.c.

967 {
968  Move *move,*moves;
969  int tmp;
970  int x_ref,y_ref;
971  int x_next,y_next;
972  int size, result;
973  int initial_size, limit_size;
974 
975  x_ref = x;
976  y_ref = y;
977 
978  x_next = cuddNextHigh(table,x);
979  y_next = cuddNextLow(table,y);
980  moves = NULL;
981  initial_size = limit_size = table->keys - table->isolated;
982 
983  for (;;) {
984  if (x_next == y_next) {
985  size = cuddSwapInPlace(table,x,x_next);
986  if (size == 0) goto ddExchangeOutOfMem;
987  move = (Move *)cuddDynamicAllocNode(table);
988  if (move == NULL) goto ddExchangeOutOfMem;
989  move->x = x;
990  move->y = x_next;
991  move->size = size;
992  move->next = moves;
993  moves = move;
994  size = cuddSwapInPlace(table,y_next,y);
995  if (size == 0) goto ddExchangeOutOfMem;
996  move = (Move *)cuddDynamicAllocNode(table);
997  if (move == NULL) goto ddExchangeOutOfMem;
998  move->x = y_next;
999  move->y = y;
1000  move->size = size;
1001  move->next = moves;
1002  moves = move;
1003  size = cuddSwapInPlace(table,x,x_next);
1004  if (size == 0) goto ddExchangeOutOfMem;
1005  move = (Move *)cuddDynamicAllocNode(table);
1006  if (move == NULL) goto ddExchangeOutOfMem;
1007  move->x = x;
1008  move->y = x_next;
1009  move->size = size;
1010  move->next = moves;
1011  moves = move;
1012 
1013  tmp = x;
1014  x = y;
1015  y = tmp;
1016  } else if (x == y_next) {
1017  size = cuddSwapInPlace(table,x,x_next);
1018  if (size == 0) goto ddExchangeOutOfMem;
1019  move = (Move *)cuddDynamicAllocNode(table);
1020  if (move == NULL) goto ddExchangeOutOfMem;
1021  move->x = x;
1022  move->y = x_next;
1023  move->size = size;
1024  move->next = moves;
1025  moves = move;
1026  tmp = x;
1027  x = y;
1028  y = tmp;
1029  } else {
1030  size = cuddSwapInPlace(table,x,x_next);
1031  if (size == 0) goto ddExchangeOutOfMem;
1032  move = (Move *)cuddDynamicAllocNode(table);
1033  if (move == NULL) goto ddExchangeOutOfMem;
1034  move->x = x;
1035  move->y = x_next;
1036  move->size = size;
1037  move->next = moves;
1038  moves = move;
1039  size = cuddSwapInPlace(table,y_next,y);
1040  if (size == 0) goto ddExchangeOutOfMem;
1041  move = (Move *)cuddDynamicAllocNode(table);
1042  if (move == NULL) goto ddExchangeOutOfMem;
1043  move->x = y_next;
1044  move->y = y;
1045  move->size = size;
1046  move->next = moves;
1047  moves = move;
1048  x = x_next;
1049  y = y_next;
1050  }
1051 
1052  x_next = cuddNextHigh(table,x);
1053  y_next = cuddNextLow(table,y);
1054  if (x_next > y_ref) break;
1055 
1056  if ((double) size > DD_MAX_REORDER_GROWTH * (double) limit_size) {
1057  break;
1058  } else if (size < limit_size) {
1059  limit_size = size;
1060  }
1061  }
1062 
1063  if (y_next>=x_ref) {
1064  size = cuddSwapInPlace(table,y_next,y);
1065  if (size == 0) goto ddExchangeOutOfMem;
1066  move = (Move *)cuddDynamicAllocNode(table);
1067  if (move == NULL) goto ddExchangeOutOfMem;
1068  move->x = y_next;
1069  move->y = y;
1070  move->size = size;
1071  move->next = moves;
1072  moves = move;
1073  }
1074 
1075  /* move backward and stop at best position or accept uphill move */
1076  result = siftBackwardProb(table,moves,initial_size,temp);
1077  if (!result) goto ddExchangeOutOfMem;
1078 
1079  while (moves != NULL) {
1080  move = moves->next;
1081  cuddDeallocMove(table, moves);
1082  moves = move;
1083  }
1084  return(1);
1085 
1086  ddExchangeOutOfMem:
1087  while (moves != NULL) {
1088  move = moves->next;
1089  cuddDeallocMove(table, moves);
1090  moves = move;
1091  }
1092  return(0);
1093 
1094 } /* end of ddExchange */
static int siftBackwardProb(DdManager *table, Move *moves, int size, double temp)
Definition: cuddInt.c:1301
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
unsigned int keys
Definition: cuddInt.h:353
DdHalfWord x
Definition: cuddInt.h:470
static int result
Definition: cuddInt.c:7466
DdHalfWord y
Definition: cuddInt.h:471
#define DD_MAX_REORDER_GROWTH
Definition: cuddInt.h:151
struct Move * next
Definition: cuddInt.h:474
int isolated
Definition: cuddInt.h:368
int size
Definition: cuddInt.h:473

◆ ddExtSymmCheck()

static int ddExtSymmCheck ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [Checks for extended symmetry of x and y.]

Description [Checks for extended symmetry of x and y. Returns 1 in case of extended symmetry; 0 otherwise.]

SideEffects [None]

Definition at line 10179 of file cuddInt.c.

10183 {
10184  DdNode *f,*f0,*f1,*f01,*f00,*f11,*f10;
10185  DdNode *one;
10186  unsigned comple; /* f0 is complemented */
10187  int notproj; /* f is not a projection function */
10188  int arccount; /* number of arcs from layer x to layer y */
10189  int TotalRefCount; /* total reference count of layer y minus 1 */
10190  int counter; /* number of nodes of layer x that are allowed */
10191  /* to violate extended symmetry conditions */
10192  int arccounter; /* number of arcs into layer y that are allowed */
10193  /* to come from layers other than x */
10194  int i;
10195  int xindex;
10196  int yindex;
10197  int res;
10198  int slots;
10199  DdNodePtr *list;
10200  DdNode *sentinel = &(table->sentinel);
10201 
10202  xindex = table->invperm[x];
10203  yindex = table->invperm[y];
10204 
10205  /* If the two variables do not interact, we do not want to merge them. */
10206  if (!cuddTestInteract(table,xindex,yindex))
10207  return(0);
10208 
10209 #ifdef DD_DEBUG
10210  /* Checks that x and y do not contain just the projection functions.
10211  ** With the test on interaction, these test become redundant,
10212  ** because an isolated projection function does not interact with
10213  ** any other variable.
10214  */
10215  if (table->subtables[x].keys == 1) {
10216  assert(table->vars[xindex]->ref != 1);
10217  }
10218  if (table->subtables[y].keys == 1) {
10219  assert(table->vars[yindex]->ref != 1);
10220  }
10221 #endif
10222 
10223 #ifdef DD_STATS
10224  extsymmcalls++;
10225 #endif
10226 
10227  arccount = 0;
10228  counter = (int) (table->subtables[x].keys *
10229  (table->symmviolation/100.0) + 0.5);
10230  one = DD_ONE(table);
10231 
10232  slots = table->subtables[x].slots;
10233  list = table->subtables[x].nodelist;
10234  for (i = 0; i < slots; i++) {
10235  f = list[i];
10236  while (f != sentinel) {
10237  /* Find f1, f0, f11, f10, f01, f00. */
10238  f1 = cuddT(f);
10239  f0 = Cudd_Regular(cuddE(f));
10240  comple = Cudd_IsComplement(cuddE(f));
10241  notproj = f1 != one || f0 != one || f->ref != (DdHalfWord) 1;
10242  if (f1->index == (unsigned) yindex) {
10243  arccount++;
10244  f11 = cuddT(f1); f10 = cuddE(f1);
10245  } else {
10246  if ((int) f0->index != yindex) {
10247  /* If f is an isolated projection function it is
10248  ** allowed to bypass layer y.
10249  */
10250  if (notproj) {
10251  if (counter == 0)
10252  return(0);
10253  counter--; /* f bypasses layer y */
10254  }
10255  }
10256  f11 = f10 = f1;
10257  }
10258  if ((int) f0->index == yindex) {
10259  arccount++;
10260  f01 = cuddT(f0); f00 = cuddE(f0);
10261  } else {
10262  f01 = f00 = f0;
10263  }
10264  if (comple) {
10265  f01 = Cudd_Not(f01);
10266  f00 = Cudd_Not(f00);
10267  }
10268 
10269  /* Unless we are looking at a projection function
10270  ** without external references except the one from the
10271  ** table, we insist that f01 == f10 or f11 == f00
10272  */
10273  if (notproj) {
10274  if (f01 != f10 && f11 != f00) {
10275  if (counter == 0)
10276  return(0);
10277  counter--;
10278  }
10279  }
10280 
10281  f = f->next;
10282  } /* while */
10283  } /* for */
10284 
10285  /* Calculate the total reference counts of y */
10286  TotalRefCount = -1; /* -1 for projection function */
10287  slots = table->subtables[y].slots;
10288  list = table->subtables[y].nodelist;
10289  for (i = 0; i < slots; i++) {
10290  f = list[i];
10291  while (f != sentinel) {
10292  TotalRefCount += f->ref;
10293  f = f->next;
10294  }
10295  }
10296 
10297  arccounter = (int) (table->subtables[y].keys *
10298  (table->arcviolation/100.0) + 0.5);
10299  res = arccount >= TotalRefCount - arccounter;
10300 
10301 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
10302  if (res) {
10303  (void) fprintf(table->out,
10304  "Found extended symmetry! x = %d\ty = %d\tPos(%d,%d)\n",
10305  xindex,yindex,x,y);
10306  }
10307 #endif
10308 
10309 #ifdef DD_STATS
10310  if (res)
10311  extsymm++;
10312 #endif
10313  return(res);
10314 
10315 } /* end ddExtSymmCheck */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
unsigned short DdHalfWord
Definition: cudd.h:253
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
#define assert(ex)
Definition: util.h:141
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
DdSubtable * subtables
Definition: cuddInt.h:349
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode sentinel
Definition: cuddInt.h:328
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:267
int symmviolation
Definition: cuddInt.h:412
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917
int arcviolation
Definition: cuddInt.h:413
int * invperm
Definition: cuddInt.h:371
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ ddFindNodeHiLo()

static void ddFindNodeHiLo ( DdManager table,
MtrNode treenode,
int *  lower,
int *  upper 
)
static

Function********************************************************************

Synopsis [Finds the lower and upper bounds of the group represented by treenode.]

Description [Finds the lower and upper bounds of the group represented by treenode. From the index and size fields we need to derive the current positions, and find maximum and minimum.]

SideEffects [The bounds are returned as side effects.]

SeeAlso []

Definition at line 8853 of file cuddInt.c.

8858 {
8859  int low;
8860  int high;
8861 
8862  /* Check whether no variables in this group already exist.
8863  ** If so, return immediately. The calling procedure will know from
8864  ** the values of upper that no reordering is needed.
8865  */
8866  if ((int) treenode->low >= table->size) {
8867  *lower = table->size;
8868  *upper = -1;
8869  return;
8870  }
8871 
8872  *lower = low = (unsigned int) table->perm[treenode->index];
8873  high = (int) (low + treenode->size - 1);
8874 
8875  if (high >= table->size) {
8876  /* This is the case of a partially existing group. The aim is to
8877  ** reorder as many variables as safely possible. If the tree
8878  ** node is terminal, we just reorder the subset of the group
8879  ** that is currently in existence. If the group has
8880  ** subgroups, then we only reorder those subgroups that are
8881  ** fully instantiated. This way we avoid breaking up a group.
8882  */
8883  MtrNode *auxnode = treenode->child;
8884  if (auxnode == NULL) {
8885  *upper = (unsigned int) table->size - 1;
8886  } else {
8887  /* Search the subgroup that strands the table->size line.
8888  ** If the first group starts at 0 and goes past table->size
8889  ** upper will get -1, thus correctly signaling that no reordering
8890  ** should take place.
8891  */
8892  while (auxnode != NULL) {
8893  int thisLower = table->perm[auxnode->low];
8894  int thisUpper = thisLower + auxnode->size - 1;
8895  if (thisUpper >= table->size && thisLower < table->size)
8896  *upper = (unsigned int) thisLower - 1;
8897  auxnode = auxnode->younger;
8898  }
8899  }
8900  } else {
8901  /* Normal case: All the variables of the group exist. */
8902  *upper = (unsigned int) high;
8903  }
8904 
8905 #ifdef DD_DEBUG
8906  /* Make sure that all variables in group are contiguous. */
8907  assert(treenode->size >= *upper - *lower + 1);
8908 #endif
8909 
8910  return;
8911 
8912 } /* end of ddFindNodeHiLo */
MtrHalfWord size
Definition: mtr.h:129
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord index
Definition: mtr.h:130
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
struct MtrNode * child
Definition: mtr.h:132
int * perm
Definition: cuddInt.h:369

◆ ddFindSupport()

static void ddFindSupport ( DdManager dd,
DdNode f,
int *  SP 
)
static

Function********************************************************************

Synopsis [Recursively find the support of f.]

Description [Recursively find the support of f. This function uses the LSB of the next field of the nodes of f as visited flag. It also uses the LSB of the next field of the variables as flag to remember whether a certain index has already been seen. Finally, it uses the manager stack to record all seen indices.]

SideEffects [The stack pointer SP is modified by side-effect. The next fields are changed and need to be reset.]

Definition at line 23953 of file cuddInt.c.

23957 {
23958 int index;
23959 DdNode *var;
23960 
23961 if (cuddIsConstant(f) || Cudd_IsComplement(f->next)) {
23962 return;
23963 }
23964 
23965 index = f->index;
23966 var = dd->vars[index];
23967 /* It is possible that var is embedded in f. That causes no problem,
23968 ** though, because if we see it after encountering another node with
23969 ** the same index, nothing is supposed to happen.
23970 */
23971 if (!Cudd_IsComplement(var->next)) {
23972 var->next = Cudd_Complement(var->next);
23973 dd->stack[*SP] = (DdNode *)(ptrint) index;
23974 (*SP)++;
23975 }
23976 ddFindSupport(dd, cuddT(f), SP);
23977 ddFindSupport(dd, Cudd_Regular(cuddE(f)), SP);
23978 /* Mark as visited. */
23979 f->next = Cudd_Complement(f->next);
23980 
23981 } /* end of ddFindSupport */
int ptrint
Definition: cuddInt.h:249
Definition: cudd.h:264
#define Cudd_Regular(node)
Definition: cudd.h:373
DdNode ** stack
Definition: cuddInt.h:364
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode * next
Definition: cudd.h:267
#define cuddIsConstant(node)
Definition: cuddInt.h:593
static void ddFindSupport(DdManager *dd, DdNode *f, int *SP)
Definition: cuddInt.c:23953
#define Cudd_Complement(node)
Definition: cudd.h:387
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625

◆ ddFixLimits()

static DD_INLINE void ddFixLimits ( DdManager unique)
static

Function********************************************************************

Synopsis [Adjusts the values of table limits.]

Description [Adjusts the values of table fields controlling the. sizes of subtables and computed table. If the computed table is too small according to the new values, it is resized.]

SideEffects [Modifies manager fields. May resize computed table.]

SeeAlso []

Definition at line 21624 of file cuddInt.c.

21626 {
21627 unique->minDead = (unsigned) (unique->gcFrac * (double) unique->slots);
21628 unique->cacheSlack = (int) ddMin(unique->maxCacheHard,
21630 2 * (int) unique->cacheSlots;
21631 if (unique->cacheSlots < unique->slots/2 && unique->cacheSlack >= 0)
21632 cuddCacheResize(unique);
21633 return;
21634 
21635 } /* end of ddFixLimits */
if(DEFINED IN_SOURCE_BUILD) set(LLVM_LINK_COMPONENTS BitWriter Core IPO IrReader InstCombine Instrumentation Target Linker Analysis ScalarOpts Support Svf Cudd) add_llvm_tool(cfl cfl.cpp) else() add_executable(cfl cfl.cpp) target_link_libraries(cfl Svf Cudd $
Definition: CMakeLists.txt:2
double gcFrac
Definition: cuddInt.h:359
unsigned int maxCacheHard
Definition: cuddInt.h:343
unsigned int slots
Definition: cuddInt.h:352
void cuddCacheResize(DdManager *table)
Definition: cuddInt.c:4955
unsigned int cacheSlots
Definition: cuddInt.h:337
#define ddMin(x, y)
Definition: cuddInt.h:771
#define DD_MAX_CACHE_TO_SLOTS_RATIO
Definition: cuddInt.h:145
int cacheSlack
Definition: cuddInt.h:342
unsigned int minDead
Definition: cuddInt.h:358

◆ ddGroupMove()

static int ddGroupMove ( DdManager table,
int  x,
int  y,
Move **  moves 
)
static

Function********************************************************************

Synopsis [Swaps two groups and records the move.]

Description [Swaps two groups and records the move. Returns the number of keys in the DD table in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 9729 of file cuddInt.c.

9734 {
9735  Move *move;
9736  int size;
9737  int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
9738  int swapx,swapy;
9739 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
9740  int initialSize,bestSize;
9741 #endif
9742 
9743 #ifdef DD_DEBUG
9744  /* We assume that x < y */
9745  assert(x < y);
9746 #endif
9747  /* Find top, bottom, and size for the two groups. */
9748  xbot = x;
9749  xtop = table->subtables[x].next;
9750  xsize = xbot - xtop + 1;
9751  ybot = y;
9752  while ((unsigned) ybot < table->subtables[ybot].next)
9753  ybot = table->subtables[ybot].next;
9754  ytop = y;
9755  ysize = ybot - ytop + 1;
9756 
9757 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
9758  initialSize = bestSize = table->keys - table->isolated;
9759 #endif
9760  /* Sift the variables of the second group up through the first group */
9761  for (i = 1; i <= ysize; i++) {
9762  for (j = 1; j <= xsize; j++) {
9763  size = cuddSwapInPlace(table,x,y);
9764  if (size == 0) goto ddGroupMoveOutOfMem;
9765 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
9766  if (size < bestSize)
9767  bestSize = size;
9768 #endif
9769  swapx = x; swapy = y;
9770  y = x;
9771  x = cuddNextLow(table,y);
9772  }
9773  y = ytop + i;
9774  x = cuddNextLow(table,y);
9775  }
9776 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
9777  if ((bestSize < initialSize) && (bestSize < size))
9778  (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size);
9779 #endif
9780 
9781  /* fix groups */
9782  y = xtop; /* ytop is now where xtop used to be */
9783  for (i = 0; i < ysize - 1; i++) {
9784  table->subtables[y].next = cuddNextHigh(table,y);
9785  y = cuddNextHigh(table,y);
9786  }
9787  table->subtables[y].next = xtop; /* y is bottom of its group, join */
9788  /* it to top of its group */
9789  x = cuddNextHigh(table,y);
9790  newxtop = x;
9791  for (i = 0; i < xsize - 1; i++) {
9792  table->subtables[x].next = cuddNextHigh(table,x);
9793  x = cuddNextHigh(table,x);
9794  }
9795  table->subtables[x].next = newxtop; /* x is bottom of its group, join */
9796  /* it to top of its group */
9797 #ifdef DD_DEBUG
9798  if (pr > 0) (void) fprintf(table->out,"ddGroupMove:\n");
9799 #endif
9800 
9801  /* Store group move */
9802  move = (Move *) cuddDynamicAllocNode(table);
9803  if (move == NULL) goto ddGroupMoveOutOfMem;
9804  move->x = swapx;
9805  move->y = swapy;
9806  move->flags = MTR_DEFAULT;
9807  move->size = table->keys - table->isolated;
9808  move->next = *moves;
9809  *moves = move;
9810 
9811  return(table->keys - table->isolated);
9812 
9813  ddGroupMoveOutOfMem:
9814  while (*moves != NULL) {
9815  move = (*moves)->next;
9816  cuddDeallocMove(table, *moves);
9817  *moves = move;
9818  }
9819  return(0);
9820 
9821 } /* end of ddGroupMove */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
#define MTR_DEFAULT
Definition: mtr.h:94
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int isolated
Definition: cuddInt.h:368
int size
Definition: cuddInt.h:473

◆ ddGroupMoveBackward()

static int ddGroupMoveBackward ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [Undoes the swap two groups.]

Description [Undoes the swap two groups. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 9835 of file cuddInt.c.

9839 {
9840  int size;
9841  int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
9842 
9843 
9844 #ifdef DD_DEBUG
9845  /* We assume that x < y */
9846  assert(x < y);
9847 #endif
9848 
9849  /* Find top, bottom, and size for the two groups. */
9850  xbot = x;
9851  xtop = table->subtables[x].next;
9852  xsize = xbot - xtop + 1;
9853  ybot = y;
9854  while ((unsigned) ybot < table->subtables[ybot].next)
9855  ybot = table->subtables[ybot].next;
9856  ytop = y;
9857  ysize = ybot - ytop + 1;
9858 
9859  /* Sift the variables of the second group up through the first group */
9860  for (i = 1; i <= ysize; i++) {
9861  for (j = 1; j <= xsize; j++) {
9862  size = cuddSwapInPlace(table,x,y);
9863  if (size == 0)
9864  return(0);
9865  y = x;
9866  x = cuddNextLow(table,y);
9867  }
9868  y = ytop + i;
9869  x = cuddNextLow(table,y);
9870  }
9871 
9872  /* fix groups */
9873  y = xtop;
9874  for (i = 0; i < ysize - 1; i++) {
9875  table->subtables[y].next = cuddNextHigh(table,y);
9876  y = cuddNextHigh(table,y);
9877  }
9878  table->subtables[y].next = xtop; /* y is bottom of its group, join */
9879  /* to its top */
9880  x = cuddNextHigh(table,y);
9881  newxtop = x;
9882  for (i = 0; i < xsize - 1; i++) {
9883  table->subtables[x].next = cuddNextHigh(table,x);
9884  x = cuddNextHigh(table,x);
9885  }
9886  table->subtables[x].next = newxtop; /* x is bottom of its group, join */
9887  /* to its top */
9888 #ifdef DD_DEBUG
9889  if (pr > 0) (void) fprintf(table->out,"ddGroupMoveBackward:\n");
9890 #endif
9891 
9892  return(1);
9893 
9894 } /* end of ddGroupMoveBackward */
#define assert(ex)
Definition: util.h:141
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
FILE * out
Definition: cuddInt.h:423
unsigned int next
Definition: cuddInt.h:317

◆ ddGroupSifting()

static int ddGroupSifting ( DdManager table,
int  lower,
int  upper,
DD_CHKFP  checkFunction,
int  lazyFlag 
)
static

Function********************************************************************

Synopsis [Sifts from treenode->low to treenode->high.]

Description [Sifts from treenode->low to treenode->high. If croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the end of the initial sifting. If a group is created, it is then sifted again. After sifting one variable, the group that contains it is dissolved. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 8956 of file cuddInt.c.

8962 {
8963  int *var;
8964  int i,j,x,xInit;
8965  int nvars;
8966  int classes;
8967  int result;
8968  int *sifted;
8969  int merged;
8970  int dissolve;
8971 #ifdef DD_STATS
8972  unsigned previousSize;
8973 #endif
8974  int xindex;
8975 
8976  nvars = table->size;
8977 
8978  /* Order variables to sift. */
8979  entry = NULL;
8980  sifted = NULL;
8981  var = ALLOC(int,nvars);
8982  if (var == NULL) {
8983  table->errorCode = CUDD_MEMORY_OUT;
8984  goto ddGroupSiftingOutOfMem;
8985  }
8986  entry = ALLOC(int,nvars);
8987  if (entry == NULL) {
8988  table->errorCode = CUDD_MEMORY_OUT;
8989  goto ddGroupSiftingOutOfMem;
8990  }
8991  sifted = ALLOC(int,nvars);
8992  if (sifted == NULL) {
8993  table->errorCode = CUDD_MEMORY_OUT;
8994  goto ddGroupSiftingOutOfMem;
8995  }
8996 
8997  /* Here we consider only one representative for each group. */
8998  for (i = 0, classes = 0; i < nvars; i++) {
8999  sifted[i] = 0;
9000  x = table->perm[i];
9001  if ((unsigned) x >= table->subtables[x].next) {
9002  entry[i] = table->subtables[x].keys;
9003  var[classes] = i;
9004  classes++;
9005  }
9006  }
9007 
9008  qsort((void *)var,classes,sizeof(int),
9010 
9011  if (lazyFlag) {
9012  for (i = 0; i < nvars; i ++) {
9013  ddResetVarHandled(table, i);
9014  }
9015  }
9016 
9017  /* Now sift. */
9018  for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) {
9019  if (ddTotalNumberSwapping >= table->siftMaxSwap)
9020  break;
9021  if (util_cpu_time() - table->startTime + table->reordTime
9022  > table->timeLimit) {
9023  table->autoDyn = 0; /* prevent further reordering */
9024  break;
9025  }
9026  xindex = var[i];
9027  if (sifted[xindex] == 1) /* variable already sifted as part of group */
9028  continue;
9029  x = table->perm[xindex]; /* find current level of this variable */
9030 
9031  if (x < lower || x > upper || table->subtables[x].bindVar == 1)
9032  continue;
9033 #ifdef DD_STATS
9034  previousSize = table->keys - table->isolated;
9035 #endif
9036 #ifdef DD_DEBUG
9037  /* x is bottom of group */
9038  assert((unsigned) x >= table->subtables[x].next);
9039 #endif
9040  if ((unsigned) x == table->subtables[x].next) {
9041  dissolve = 1;
9042  result = ddGroupSiftingAux(table,x,lower,upper,checkFunction,
9043  lazyFlag);
9044  } else {
9045  dissolve = 0;
9046  result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag);
9047  }
9048  if (!result) goto ddGroupSiftingOutOfMem;
9049 
9050  /* check for aggregation */
9051  merged = 0;
9052  if (lazyFlag == 0 && table->groupcheck == CUDD_GROUP_CHECK7) {
9053  x = table->perm[xindex]; /* find current level */
9054  if ((unsigned) x == table->subtables[x].next) { /* not part of a group */
9055  if (x != upper && sifted[table->invperm[x+1]] == 0 &&
9056  (unsigned) x+1 == table->subtables[x+1].next) {
9057  if (ddSecDiffCheck(table,x,x+1)) {
9058  merged =1;
9059  ddCreateGroup(table,x,x+1);
9060  }
9061  }
9062  if (x != lower && sifted[table->invperm[x-1]] == 0 &&
9063  (unsigned) x-1 == table->subtables[x-1].next) {
9064  if (ddSecDiffCheck(table,x-1,x)) {
9065  merged =1;
9066  ddCreateGroup(table,x-1,x);
9067  }
9068  }
9069  }
9070  }
9071 
9072  if (merged) { /* a group was created */
9073  /* move x to bottom of group */
9074  while ((unsigned) x < table->subtables[x].next)
9075  x = table->subtables[x].next;
9076  /* sift */
9077  result = ddGroupSiftingAux(table,x,lower,upper,ddNoCheck,lazyFlag);
9078  if (!result) goto ddGroupSiftingOutOfMem;
9079 #ifdef DD_STATS
9080  if (table->keys < previousSize + table->isolated) {
9081  (void) fprintf(table->out,"_");
9082  } else if (table->keys > previousSize + table->isolated) {
9083  (void) fprintf(table->out,"^");
9084  } else {
9085  (void) fprintf(table->out,"*");
9086  }
9087  fflush(table->out);
9088  } else {
9089  if (table->keys < previousSize + table->isolated) {
9090  (void) fprintf(table->out,"-");
9091  } else if (table->keys > previousSize + table->isolated) {
9092  (void) fprintf(table->out,"+");
9093  } else {
9094  (void) fprintf(table->out,"=");
9095  }
9096  fflush(table->out);
9097 #endif
9098  }
9099 
9100  /* Mark variables in the group just sifted. */
9101  x = table->perm[xindex];
9102  if ((unsigned) x != table->subtables[x].next) {
9103  xInit = x;
9104  do {
9105  j = table->invperm[x];
9106  sifted[j] = 1;
9107  x = table->subtables[x].next;
9108  } while (x != xInit);
9109 
9110  /* Dissolve the group if it was created. */
9111  if (lazyFlag == 0 && dissolve) {
9112  do {
9113  j = table->subtables[x].next;
9114  table->subtables[x].next = x;
9115  x = j;
9116  } while (x != xInit);
9117  }
9118  }
9119 
9120 #ifdef DD_DEBUG
9121  if (pr > 0) (void) fprintf(table->out,"ddGroupSifting:");
9122 #endif
9123 
9124  if (lazyFlag) ddSetVarHandled(table, xindex);
9125  } /* for */
9126 
9127  FREE(sifted);
9128  FREE(var);
9129  FREE(entry);
9130 
9131  return(1);
9132 
9133  ddGroupSiftingOutOfMem:
9134  if (entry != NULL) FREE(entry);
9135  if (var != NULL) FREE(var);
9136  if (sifted != NULL) FREE(sifted);
9137 
9138  return(0);
9139 
9140 } /* end of ddGroupSifting */
Cudd_AggregationType groupcheck
Definition: cuddInt.h:410
unsigned int keys
Definition: cuddInt.h:314
static int ddUniqueCompareGroup(int *ptrX, int *ptrY)
Definition: cuddInt.c:8928
unsigned long reordTime
Definition: cuddInt.h:434
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:302
unsigned long startTime
Definition: cuddInt.h:426
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
static int ddGroupSiftingAux(DdManager *table, int x, int xLow, int xHigh, DD_CHKFP checkFunction, int lazyFlag)
Definition: cuddInt.c:9197
static int ddSecDiffCheck(DdManager *table, int x, int y)
Definition: cuddInt.c:10122
int bindVar
Definition: cuddInt.h:318
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static void ddCreateGroup(DdManager *table, int x, int y)
Definition: cuddInt.c:9156
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: util.c:34
int siftMaxVar
Definition: cuddInt.h:395
static int result
Definition: cuddInt.c:7466
static int ddSetVarHandled(DdManager *dd, int index)
Definition: cuddInt.c:10369
static int ddNoCheck(DdManager *table, int x, int y)
Definition: cuddInt.c:10098
unsigned int next
Definition: cuddInt.h:317
static int ddResetVarHandled(DdManager *dd, int index)
Definition: cuddInt.c:10393
static int * entry
Definition: cuddInt.c:8422
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int ddTotalNumberSwapping
Definition: cuddInt.c:14489
int autoDyn
Definition: cuddInt.h:400
int * perm
Definition: cuddInt.h:369
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ ddGroupSiftingAux()

static int ddGroupSiftingAux ( DdManager table,
int  x,
int  xLow,
int  xHigh,
DD_CHKFP  checkFunction,
int  lazyFlag 
)
static

Function********************************************************************

Synopsis [Sifts one variable up and down until it has taken all positions. Checks for aggregation.]

Description [Sifts one variable up and down until it has taken all positions. Checks for aggregation. There may be at most two sweeps, even if the group grows. Assumes that x is either an isolated variable, or it is the bottom of a group. All groups may not have been found. The variable being moved is returned to the best position seen during sifting. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 9197 of file cuddInt.c.

9204 {
9205  Move *move;
9206  Move *moves; /* list of moves */
9207  int initialSize;
9208  int result;
9209  int y;
9210  int topbot;
9211 
9212 #ifdef DD_DEBUG
9213  if (pr > 0) (void) fprintf(table->out,
9214  "ddGroupSiftingAux from %d to %d\n",xLow,xHigh);
9215  assert((unsigned) x >= table->subtables[x].next); /* x is bottom of group */
9216 #endif
9217 
9218  initialSize = table->keys - table->isolated;
9219  moves = NULL;
9220 
9221  originalSize = initialSize; /* for lazy sifting */
9222 
9223  /* If we have a singleton, we check for aggregation in both
9224  ** directions before we sift.
9225  */
9226  if ((unsigned) x == table->subtables[x].next) {
9227  /* Will go down first, unless x == xHigh:
9228  ** Look for aggregation above x.
9229  */
9230  for (y = x; y > xLow; y--) {
9231  if (!checkFunction(table,y-1,y))
9232  break;
9233  topbot = table->subtables[y-1].next; /* find top of y-1's group */
9234  table->subtables[y-1].next = y;
9235  table->subtables[x].next = topbot; /* x is bottom of group so its */
9236  /* next is top of y-1's group */
9237  y = topbot + 1; /* add 1 for y--; new y is top of group */
9238  }
9239  /* Will go up first unless x == xlow:
9240  ** Look for aggregation below x.
9241  */
9242  for (y = x; y < xHigh; y++) {
9243  if (!checkFunction(table,y,y+1))
9244  break;
9245  /* find bottom of y+1's group */
9246  topbot = y + 1;
9247  while ((unsigned) topbot < table->subtables[topbot].next) {
9248  topbot = table->subtables[topbot].next;
9249  }
9250  table->subtables[topbot].next = table->subtables[y].next;
9251  table->subtables[y].next = y + 1;
9252  y = topbot - 1; /* subtract 1 for y++; new y is bottom of group */
9253  }
9254  }
9255 
9256  /* Now x may be in the middle of a group.
9257  ** Find bottom of x's group.
9258  */
9259  while ((unsigned) x < table->subtables[x].next)
9260  x = table->subtables[x].next;
9261 
9262  if (x == xLow) { /* Sift down */
9263 #ifdef DD_DEBUG
9264  /* x must be a singleton */
9265  assert((unsigned) x == table->subtables[x].next);
9266 #endif
9267  if (x == xHigh) return(1); /* just one variable */
9268 
9269  if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves))
9270  goto ddGroupSiftingAuxOutOfMem;
9271  /* at this point x == xHigh, unless early term */
9272 
9273  /* move backward and stop at best position */
9274  result = ddGroupSiftingBackward(table,moves,initialSize,
9275  DD_SIFT_DOWN,lazyFlag);
9276 #ifdef DD_DEBUG
9277  assert(table->keys - table->isolated <= (unsigned) initialSize);
9278 #endif
9279  if (!result) goto ddGroupSiftingAuxOutOfMem;
9280 
9281  } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */
9282 #ifdef DD_DEBUG
9283  /* x is bottom of group */
9284  assert((unsigned) x >= table->subtables[x].next);
9285 #endif
9286  /* Find top of x's group */
9287  x = table->subtables[x].next;
9288 
9289  if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves))
9290  goto ddGroupSiftingAuxOutOfMem;
9291  /* at this point x == xLow, unless early term */
9292 
9293  /* move backward and stop at best position */
9294  result = ddGroupSiftingBackward(table,moves,initialSize,
9295  DD_SIFT_UP,lazyFlag);
9296 #ifdef DD_DEBUG
9297  assert(table->keys - table->isolated <= (unsigned) initialSize);
9298 #endif
9299  if (!result) goto ddGroupSiftingAuxOutOfMem;
9300 
9301  } else if (x - xLow > xHigh - x) { /* must go down first: shorter */
9302  if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves))
9303  goto ddGroupSiftingAuxOutOfMem;
9304  /* at this point x == xHigh, unless early term */
9305 
9306  /* Find top of group */
9307  if (moves) {
9308  x = moves->y;
9309  }
9310  while ((unsigned) x < table->subtables[x].next)
9311  x = table->subtables[x].next;
9312  x = table->subtables[x].next;
9313 #ifdef DD_DEBUG
9314  /* x should be the top of a group */
9315  assert((unsigned) x <= table->subtables[x].next);
9316 #endif
9317 
9318  if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves))
9319  goto ddGroupSiftingAuxOutOfMem;
9320 
9321  /* move backward and stop at best position */
9322  result = ddGroupSiftingBackward(table,moves,initialSize,
9323  DD_SIFT_UP,lazyFlag);
9324 #ifdef DD_DEBUG
9325  assert(table->keys - table->isolated <= (unsigned) initialSize);
9326 #endif
9327  if (!result) goto ddGroupSiftingAuxOutOfMem;
9328 
9329  } else { /* moving up first: shorter */
9330  /* Find top of x's group */
9331  x = table->subtables[x].next;
9332 
9333  if (!ddGroupSiftingUp(table,x,xLow,checkFunction,&moves))
9334  goto ddGroupSiftingAuxOutOfMem;
9335  /* at this point x == xHigh, unless early term */
9336 
9337  if (moves) {
9338  x = moves->x;
9339  }
9340  while ((unsigned) x < table->subtables[x].next)
9341  x = table->subtables[x].next;
9342 #ifdef DD_DEBUG
9343  /* x is bottom of a group */
9344  assert((unsigned) x >= table->subtables[x].next);
9345 #endif
9346 
9347  if (!ddGroupSiftingDown(table,x,xHigh,checkFunction,&moves))
9348  goto ddGroupSiftingAuxOutOfMem;
9349 
9350  /* move backward and stop at best position */
9351  result = ddGroupSiftingBackward(table,moves,initialSize,
9352  DD_SIFT_DOWN,lazyFlag);
9353 #ifdef DD_DEBUG
9354  assert(table->keys - table->isolated <= (unsigned) initialSize);
9355 #endif
9356  if (!result) goto ddGroupSiftingAuxOutOfMem;
9357  }
9358 
9359  while (moves != NULL) {
9360  move = moves->next;
9361  cuddDeallocMove(table, moves);
9362  moves = move;
9363  }
9364 
9365  return(1);
9366 
9367  ddGroupSiftingAuxOutOfMem:
9368  while (moves != NULL) {
9369  move = moves->next;
9370  cuddDeallocMove(table, moves);
9371  moves = move;
9372  }
9373 
9374  return(0);
9375 
9376 } /* end of ddGroupSiftingAux */
#define DD_SIFT_UP
Definition: cuddInt.c:8396
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
static unsigned int originalSize
Definition: cuddInt.c:8436
Definition: cuddInt.h:469
static int ddGroupSiftingBackward(DdManager *table, Move *moves, int size, int upFlag, int lazyFlag)
Definition: cuddInt.c:9909
DdSubtable * subtables
Definition: cuddInt.h:349
static int ddGroupSiftingUp(DdManager *table, int y, int xLow, DD_CHKFP checkFunction, Move **moves)
Definition: cuddInt.c:9395
#define DD_SIFT_DOWN
Definition: cuddInt.c:8395
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
DdHalfWord x
Definition: cuddInt.h:470
static int result
Definition: cuddInt.c:7466
DdHalfWord y
Definition: cuddInt.h:471
static int ddGroupSiftingDown(DdManager *table, int x, int xHigh, DD_CHKFP checkFunction, Move **moves)
Definition: cuddInt.c:9553
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int isolated
Definition: cuddInt.h:368

◆ ddGroupSiftingBackward()

static int ddGroupSiftingBackward ( DdManager table,
Move moves,
int  size,
int  upFlag,
int  lazyFlag 
)
static

Function********************************************************************

Synopsis [Determines the best position for a variables and returns it there.]

Description [Determines the best position for a variables and returns it there. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 9909 of file cuddInt.c.

9915 {
9916  Move *move;
9917  int res;
9918  Move *end_move;
9919  int diff, tmp_diff;
9920  int index;
9921  unsigned int pairlev;
9922 
9923  if (lazyFlag) {
9924  end_move = NULL;
9925 
9926  /* Find the minimum size, and the earliest position at which it
9927  ** was achieved. */
9928  for (move = moves; move != NULL; move = move->next) {
9929  if (move->size < size) {
9930  size = move->size;
9931  end_move = move;
9932  } else if (move->size == size) {
9933  if (end_move == NULL) end_move = move;
9934  }
9935  }
9936 
9937  /* Find among the moves that give minimum size the one that
9938  ** minimizes the distance from the corresponding variable. */
9939  if (moves != NULL) {
9940  diff = Cudd_ReadSize(table) + 1;
9941  index = (upFlag == 1) ?
9942  table->invperm[moves->x] : table->invperm[moves->y];
9943  pairlev =
9944  (unsigned) table->perm[Cudd_bddReadPairIndex(table, index)];
9945 
9946  for (move = moves; move != NULL; move = move->next) {
9947  if (move->size == size) {
9948  if (upFlag == 1) {
9949  tmp_diff = (move->x > pairlev) ?
9950  move->x - pairlev : pairlev - move->x;
9951  } else {
9952  tmp_diff = (move->y > pairlev) ?
9953  move->y - pairlev : pairlev - move->y;
9954  }
9955  if (tmp_diff < diff) {
9956  diff = tmp_diff;
9957  end_move = move;
9958  }
9959  }
9960  }
9961  }
9962  } else {
9963  /* Find the minimum size. */
9964  for (move = moves; move != NULL; move = move->next) {
9965  if (move->size < size) {
9966  size = move->size;
9967  }
9968  }
9969  }
9970 
9971  /* In case of lazy sifting, end_move identifies the position at
9972  ** which we want to stop. Otherwise, we stop as soon as we meet
9973  ** the minimum size. */
9974  for (move = moves; move != NULL; move = move->next) {
9975  if (lazyFlag) {
9976  if (move == end_move) return(1);
9977  } else {
9978  if (move->size == size) return(1);
9979  }
9980  if ((table->subtables[move->x].next == move->x) &&
9981  (table->subtables[move->y].next == move->y)) {
9982  res = cuddSwapInPlace(table,(int)move->x,(int)move->y);
9983  if (!res) return(0);
9984 #ifdef DD_DEBUG
9985  if (pr > 0) (void) fprintf(table->out,"ddGroupSiftingBackward:\n");
9986  assert(table->subtables[move->x].next == move->x);
9987  assert(table->subtables[move->y].next == move->y);
9988 #endif
9989  } else { /* Group move necessary */
9990  if (move->flags == MTR_NEWNODE) {
9991  ddDissolveGroup(table,(int)move->x,(int)move->y);
9992  } else {
9993  res = ddGroupMoveBackward(table,(int)move->x,(int)move->y);
9994  if (!res) return(0);
9995  }
9996  }
9997 
9998  }
9999 
10000  return(1);
10001 
10002 } /* end of ddGroupSiftingBackward */
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define MTR_NEWNODE
Definition: mtr.h:98
int Cudd_bddReadPairIndex(DdManager *dd, int index)
Definition: cuddInt.c:2044
static void ddDissolveGroup(DdManager *table, int x, int y)
Definition: cuddInt.c:10064
int Cudd_ReadSize(DdManager *dd)
Definition: cuddInt.c:1787
static int ddGroupMoveBackward(DdManager *table, int x, int y)
Definition: cuddInt.c:9835
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int * invperm
Definition: cuddInt.h:371
int * perm
Definition: cuddInt.h:369
int size
Definition: cuddInt.h:473

◆ ddGroupSiftingDown()

static int ddGroupSiftingDown ( DdManager table,
int  x,
int  xHigh,
DD_CHKFP  checkFunction,
Move **  moves 
)
static

Function********************************************************************

Synopsis [Sifts down a variable until it reaches position xHigh.]

Description [Sifts down a variable until it reaches position xHigh. Assumes that x is the bottom of a group (or a singleton). Records all the moves. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 9553 of file cuddInt.c.

9559 {
9560  Move *move;
9561  int y;
9562  int size;
9563  int limitSize;
9564  int gxtop,gybot;
9565  int R; /* upper bound on node decrease */
9566  int xindex, yindex;
9567  int isolated, allVars;
9568  int z;
9569  int zindex;
9570 #ifdef DD_DEBUG
9571  int checkR;
9572 #endif
9573 
9574  /* If the group consists of simple variables, there is no point in
9575  ** sifting it down. This check is redundant if the projection functions
9576  ** do not have external references, because the computation of the
9577  ** lower bound takes care of the problem. It is necessary otherwise to
9578  ** prevent the sifting down of simple variables. */
9579  y = x;
9580  allVars = 1;
9581  do {
9582  if (table->subtables[y].keys != 1) {
9583  allVars = 0;
9584  break;
9585  }
9586  y = table->subtables[y].next;
9587  } while (table->subtables[y].next != (unsigned) x);
9588  if (allVars)
9589  return(1);
9590 
9591  /* Initialize R. */
9592  xindex = table->invperm[x];
9593  gxtop = table->subtables[x].next;
9594  limitSize = size = table->keys - table->isolated;
9595  R = 0;
9596  for (z = xHigh; z > gxtop; z--) {
9597  zindex = table->invperm[z];
9598  if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) {
9599  isolated = table->vars[zindex]->ref == 1;
9600  R += table->subtables[z].keys - isolated;
9601  }
9602  }
9603 
9604  y = cuddNextHigh(table,x);
9605  while (y <= xHigh && size - R < limitSize) {
9606 #ifdef DD_DEBUG
9607  gxtop = table->subtables[x].next;
9608  checkR = 0;
9609  for (z = xHigh; z > gxtop; z--) {
9610  zindex = table->invperm[z];
9611  if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) {
9612  isolated = table->vars[zindex]->ref == 1;
9613  checkR += table->subtables[z].keys - isolated;
9614  }
9615  }
9616  assert(R >= checkR);
9617 #endif
9618  /* Find bottom of y group. */
9619  gybot = table->subtables[y].next;
9620  while (table->subtables[gybot].next != (unsigned) y)
9621  gybot = table->subtables[gybot].next;
9622 
9623  if (checkFunction(table,x,y)) {
9624  /* Group found: attach groups and record move. */
9625  gxtop = table->subtables[x].next;
9626  table->subtables[x].next = y;
9627  table->subtables[gybot].next = gxtop;
9628  move = (Move *)cuddDynamicAllocNode(table);
9629  if (move == NULL) goto ddGroupSiftingDownOutOfMem;
9630  move->x = x;
9631  move->y = y;
9632  move->flags = MTR_NEWNODE;
9633  move->size = table->keys - table->isolated;
9634  move->next = *moves;
9635  *moves = move;
9636  } else if (table->subtables[x].next == (unsigned) x &&
9637  table->subtables[y].next == (unsigned) y) {
9638  /* x and y are self groups */
9639  /* Update upper bound on node decrease. */
9640  yindex = table->invperm[y];
9641  if (cuddTestInteract(table,xindex,yindex)) {
9642  isolated = table->vars[yindex]->ref == 1;
9643  R -= table->subtables[y].keys - isolated;
9644  }
9645  size = cuddSwapInPlace(table,x,y);
9646 #ifdef DD_DEBUG
9647  assert(table->subtables[x].next == (unsigned) x);
9648  assert(table->subtables[y].next == (unsigned) y);
9649 #endif
9650  if (size == 0) goto ddGroupSiftingDownOutOfMem;
9651 
9652  /* Record move. */
9653  move = (Move *) cuddDynamicAllocNode(table);
9654  if (move == NULL) goto ddGroupSiftingDownOutOfMem;
9655  move->x = x;
9656  move->y = y;
9657  move->flags = MTR_DEFAULT;
9658  move->size = size;
9659  move->next = *moves;
9660  *moves = move;
9661 
9662 #ifdef DD_DEBUG
9663  if (pr > 0) (void) fprintf(table->out,
9664  "ddGroupSiftingDown (2 single groups):\n");
9665 #endif
9666  if ((double) size > (double) limitSize * table->maxGrowth)
9667  return(1);
9668  if (size < limitSize) limitSize = size;
9669 
9670  x = y;
9671  y = cuddNextHigh(table,x);
9672  } else { /* Group move */
9673  /* Update upper bound on node decrease: first phase. */
9674  gxtop = table->subtables[x].next;
9675  z = gxtop + 1;
9676  do {
9677  zindex = table->invperm[z];
9678  if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) {
9679  isolated = table->vars[zindex]->ref == 1;
9680  R -= table->subtables[z].keys - isolated;
9681  }
9682  z++;
9683  } while (z <= gybot);
9684  size = ddGroupMove(table,x,y,moves);
9685  if (size == 0) goto ddGroupSiftingDownOutOfMem;
9686  if ((double) size > (double) limitSize * table->maxGrowth)
9687  return(1);
9688  if (size < limitSize) limitSize = size;
9689 
9690  /* Update upper bound on node decrease: second phase. */
9691  gxtop = table->subtables[gybot].next;
9692  for (z = gxtop + 1; z <= gybot; z++) {
9693  zindex = table->invperm[z];
9694  if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) {
9695  isolated = table->vars[zindex]->ref == 1;
9696  R += table->subtables[z].keys - isolated;
9697  }
9698  }
9699  }
9700  x = gybot;
9701  y = cuddNextHigh(table,x);
9702  }
9703 
9704  return(1);
9705 
9706  ddGroupSiftingDownOutOfMem:
9707  while (*moves != NULL) {
9708  move = (*moves)->next;
9709  cuddDeallocMove(table, *moves);
9710  *moves = move;
9711  }
9712 
9713  return(0);
9714 
9715 } /* end of ddGroupSiftingDown */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
static int ddGroupMove(DdManager *table, int x, int y, Move **moves)
Definition: cuddInt.c:9729
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
#define MTR_DEFAULT
Definition: mtr.h:94
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define MTR_NEWNODE
Definition: mtr.h:98
DdHalfWord y
Definition: cuddInt.h:471
DdNode ** vars
Definition: cuddInt.h:373
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int size
Definition: cuddInt.h:473

◆ ddGroupSiftingUp()

static int ddGroupSiftingUp ( DdManager table,
int  y,
int  xLow,
DD_CHKFP  checkFunction,
Move **  moves 
)
static

Function********************************************************************

Synopsis [Sifts up a variable until either it reaches position xLow or the size of the DD heap increases too much.]

Description [Sifts up a variable until either it reaches position xLow or the size of the DD heap increases too much. Assumes that y is the top of a group (or a singleton). Checks y for aggregation to the adjacent variables. Records all the moves that are appended to the list of moves received as input and returned as a side effect. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 9395 of file cuddInt.c.

9401 {
9402  Move *move;
9403  int x;
9404  int size;
9405  int i;
9406  int gxtop,gybot;
9407  int limitSize;
9408  int xindex, yindex;
9409  int zindex;
9410  int z;
9411  int isolated;
9412  int L; /* lower bound on DD size */
9413 #ifdef DD_DEBUG
9414  int checkL;
9415 #endif
9416 
9417  yindex = table->invperm[y];
9418 
9419  /* Initialize the lower bound.
9420  ** The part of the DD below the bottom of y's group will not change.
9421  ** The part of the DD above y that does not interact with any
9422  ** variable of y's group will not change.
9423  ** The rest may vanish in the best case, except for
9424  ** the nodes at level xLow, which will not vanish, regardless.
9425  ** What we use here is not really a lower bound, because we ignore
9426  ** the interactions with all variables except y.
9427  */
9428  limitSize = L = table->keys - table->isolated;
9429  gybot = y;
9430  while ((unsigned) gybot < table->subtables[gybot].next)
9431  gybot = table->subtables[gybot].next;
9432  for (z = xLow + 1; z <= gybot; z++) {
9433  zindex = table->invperm[z];
9434  if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) {
9435  isolated = table->vars[zindex]->ref == 1;
9436  L -= table->subtables[z].keys - isolated;
9437  }
9438  }
9439 
9440  x = cuddNextLow(table,y);
9441  while (x >= xLow && L <= limitSize) {
9442 #ifdef DD_DEBUG
9443  gybot = y;
9444  while ((unsigned) gybot < table->subtables[gybot].next)
9445  gybot = table->subtables[gybot].next;
9446  checkL = table->keys - table->isolated;
9447  for (z = xLow + 1; z <= gybot; z++) {
9448  zindex = table->invperm[z];
9449  if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) {
9450  isolated = table->vars[zindex]->ref == 1;
9451  checkL -= table->subtables[z].keys - isolated;
9452  }
9453  }
9454  if (pr > 0 && L != checkL) {
9455  (void) fprintf(table->out,
9456  "Inaccurate lower bound: L = %d checkL = %d\n",
9457  L, checkL);
9458  }
9459 #endif
9460  gxtop = table->subtables[x].next;
9461  if (checkFunction(table,x,y)) {
9462  /* Group found, attach groups */
9463  table->subtables[x].next = y;
9464  i = table->subtables[y].next;
9465  while (table->subtables[i].next != (unsigned) y)
9466  i = table->subtables[i].next;
9467  table->subtables[i].next = gxtop;
9468  move = (Move *)cuddDynamicAllocNode(table);
9469  if (move == NULL) goto ddGroupSiftingUpOutOfMem;
9470  move->x = x;
9471  move->y = y;
9472  move->flags = MTR_NEWNODE;
9473  move->size = table->keys - table->isolated;
9474  move->next = *moves;
9475  *moves = move;
9476  } else if (table->subtables[x].next == (unsigned) x &&
9477  table->subtables[y].next == (unsigned) y) {
9478  /* x and y are self groups */
9479  xindex = table->invperm[x];
9480  size = cuddSwapInPlace(table,x,y);
9481 #ifdef DD_DEBUG
9482  assert(table->subtables[x].next == (unsigned) x);
9483  assert(table->subtables[y].next == (unsigned) y);
9484 #endif
9485  if (size == 0) goto ddGroupSiftingUpOutOfMem;
9486  /* Update the lower bound. */
9487  if (cuddTestInteract(table,xindex,yindex)) {
9488  isolated = table->vars[xindex]->ref == 1;
9489  L += table->subtables[y].keys - isolated;
9490  }
9491  move = (Move *)cuddDynamicAllocNode(table);
9492  if (move == NULL) goto ddGroupSiftingUpOutOfMem;
9493  move->x = x;
9494  move->y = y;
9495  move->flags = MTR_DEFAULT;
9496  move->size = size;
9497  move->next = *moves;
9498  *moves = move;
9499 
9500 #ifdef DD_DEBUG
9501  if (pr > 0) (void) fprintf(table->out,
9502  "ddGroupSiftingUp (2 single groups):\n");
9503 #endif
9504  if ((double) size > (double) limitSize * table->maxGrowth)
9505  return(1);
9506  if (size < limitSize) limitSize = size;
9507  } else { /* Group move */
9508  size = ddGroupMove(table,x,y,moves);
9509  if (size == 0) goto ddGroupSiftingUpOutOfMem;
9510  /* Update the lower bound. */
9511  z = (*moves)->y;
9512  do {
9513  zindex = table->invperm[z];
9514  if (cuddTestInteract(table,zindex,yindex)) {
9515  isolated = table->vars[zindex]->ref == 1;
9516  L += table->subtables[z].keys - isolated;
9517  }
9518  z = table->subtables[z].next;
9519  } while (z != (int) (*moves)->y);
9520  if ((double) size > (double) limitSize * table->maxGrowth)
9521  return(1);
9522  if (size < limitSize) limitSize = size;
9523  }
9524  y = gxtop;
9525  x = cuddNextLow(table,y);
9526  }
9527 
9528  return(1);
9529 
9530  ddGroupSiftingUpOutOfMem:
9531  while (*moves != NULL) {
9532  move = (*moves)->next;
9533  cuddDeallocMove(table, *moves);
9534  *moves = move;
9535  }
9536  return(0);
9537 
9538 } /* end of ddGroupSiftingUp */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
static int ddGroupMove(DdManager *table, int x, int y, Move **moves)
Definition: cuddInt.c:9729
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
#define MTR_DEFAULT
Definition: mtr.h:94
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define MTR_NEWNODE
Definition: mtr.h:98
DdHalfWord y
Definition: cuddInt.h:471
DdNode ** vars
Definition: cuddInt.h:373
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int size
Definition: cuddInt.h:473

◆ ddIsVarHandled()

static int ddIsVarHandled ( DdManager dd,
int  index 
)
static

Function********************************************************************

Synopsis [Checks whether a variables is already handled.]

Description [Checks whether a variables is already handled. This function is used for lazy sifting.]

SideEffects [none]

SeeAlso []

Definition at line 10417 of file cuddInt.c.

10420 {
10421  if (index >= dd->size || index < 0) return(-1);
10422  return dd->subtables[dd->perm[index]].varHandled;
10423 
10424 } /* end of ddIsVarHandled */
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
int varHandled
Definition: cuddInt.h:322
int * perm
Definition: cuddInt.h:369

◆ ddJumpingAux()

static int ddJumpingAux ( DdManager table,
int  x,
int  x_low,
int  x_high,
double  temp 
)
static

Function********************************************************************

Synopsis [Moves a variable to a specified position.]

Description [If x==x_low, it executes jumping_down. If x==x_high, it executes jumping_up. This funcion is similar to ddSiftingAux. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 1111 of file cuddInt.c.

1117 {
1118  Move *move;
1119  Move *moves; /* list of moves */
1120  int initial_size;
1121  int result;
1122 
1123  initial_size = table->keys - table->isolated;
1124 
1125 #ifdef DD_DEBUG
1126  assert(table->subtables[x].keys > 0);
1127 #endif
1128 
1129  moves = NULL;
1130 
1131  if (cuddNextLow(table,x) < x_low) {
1132  if (cuddNextHigh(table,x) > x_high) return(1);
1133  moves = ddJumpingDown(table,x,x_high,initial_size);
1134  /* after that point x --> x_high unless early termination */
1135  if (moves == NULL) goto ddJumpingAuxOutOfMem;
1136  /* move backward and stop at best position or accept uphill move */
1137  result = siftBackwardProb(table,moves,initial_size,temp);
1138  if (!result) goto ddJumpingAuxOutOfMem;
1139  } else if (cuddNextHigh(table,x) > x_high) {
1140  moves = ddJumpingUp(table,x,x_low,initial_size);
1141  /* after that point x --> x_low unless early termination */
1142  if (moves == NULL) goto ddJumpingAuxOutOfMem;
1143  /* move backward and stop at best position or accept uphill move */
1144  result = siftBackwardProb(table,moves,initial_size,temp);
1145  if (!result) goto ddJumpingAuxOutOfMem;
1146  } else {
1147  (void) fprintf(table->err,"Unexpected condition in ddJumping\n");
1148  goto ddJumpingAuxOutOfMem;
1149  }
1150  while (moves != NULL) {
1151  move = moves->next;
1152  cuddDeallocMove(table, moves);
1153  moves = move;
1154  }
1155  return(1);
1156 
1157  ddJumpingAuxOutOfMem:
1158  while (moves != NULL) {
1159  move = moves->next;
1160  cuddDeallocMove(table, moves);
1161  moves = move;
1162  }
1163  return(0);
1164 
1165 } /* end of ddJumpingAux */
unsigned int keys
Definition: cuddInt.h:314
static int siftBackwardProb(DdManager *table, Move *moves, int size, double temp)
Definition: cuddInt.c:1301
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
static Move * ddJumpingDown(DdManager *table, int x, int x_high, int initial_size)
Definition: cuddInt.c:1241
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
FILE * err
Definition: cuddInt.h:424
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
unsigned int keys
Definition: cuddInt.h:353
static Move * ddJumpingUp(DdManager *table, int x, int x_low, int initial_size)
Definition: cuddInt.c:1182
static int result
Definition: cuddInt.c:7466
struct Move * next
Definition: cuddInt.h:474
int isolated
Definition: cuddInt.h:368

◆ ddJumpingDown()

static Move * ddJumpingDown ( DdManager table,
int  x,
int  x_high,
int  initial_size 
)
static

Function********************************************************************

Synopsis [This function is for jumping down.]

Description [This is a simplified version of ddSiftingDown. It does not use lower bounding. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

SeeAlso []

Definition at line 1241 of file cuddInt.c.

1246 {
1247  Move *moves;
1248  Move *move;
1249  int y;
1250  int size;
1251  int limit_size = initial_size;
1252 
1253  moves = NULL;
1254  y = cuddNextHigh(table,x);
1255  while (y <= x_high) {
1256  size = cuddSwapInPlace(table,x,y);
1257  if (size == 0) goto ddJumpingDownOutOfMem;
1258  move = (Move *)cuddDynamicAllocNode(table);
1259  if (move == NULL) goto ddJumpingDownOutOfMem;
1260  move->x = x;
1261  move->y = y;
1262  move->size = size;
1263  move->next = moves;
1264  moves = move;
1265  if ((double) size > table->maxGrowth * (double) limit_size) {
1266  break;
1267  } else if (size < limit_size) {
1268  limit_size = size;
1269  }
1270  x = y;
1271  y = cuddNextHigh(table,x);
1272  }
1273  return(moves);
1274 
1275  ddJumpingDownOutOfMem:
1276  while (moves != NULL) {
1277  move = moves->next;
1278  cuddDeallocMove(table, moves);
1279  moves = move;
1280  }
1281  return(NULL);
1282 
1283 } /* end of ddJumpingDown */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
DdHalfWord x
Definition: cuddInt.h:470
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473

◆ ddJumpingUp()

static Move * ddJumpingUp ( DdManager table,
int  x,
int  x_low,
int  initial_size 
)
static

Function********************************************************************

Synopsis [This function is for jumping up.]

Description [This is a simplified version of ddSiftingUp. It does not use lower bounding. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

SeeAlso []

Definition at line 1182 of file cuddInt.c.

1187 {
1188  Move *moves;
1189  Move *move;
1190  int y;
1191  int size;
1192  int limit_size = initial_size;
1193 
1194  moves = NULL;
1195  y = cuddNextLow(table,x);
1196  while (y >= x_low) {
1197  size = cuddSwapInPlace(table,y,x);
1198  if (size == 0) goto ddJumpingUpOutOfMem;
1199  move = (Move *)cuddDynamicAllocNode(table);
1200  if (move == NULL) goto ddJumpingUpOutOfMem;
1201  move->x = y;
1202  move->y = x;
1203  move->size = size;
1204  move->next = moves;
1205  moves = move;
1206  if ((double) size > table->maxGrowth * (double) limit_size) {
1207  break;
1208  } else if (size < limit_size) {
1209  limit_size = size;
1210  }
1211  x = y;
1212  y = cuddNextLow(table,x);
1213  }
1214  return(moves);
1215 
1216  ddJumpingUpOutOfMem:
1217  while (moves != NULL) {
1218  move = moves->next;
1219  cuddDeallocMove(table, moves);
1220  moves = move;
1221  }
1222  return(NULL);
1223 
1224 } /* end of ddJumpingUp */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
DdHalfWord x
Definition: cuddInt.h:470
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473

◆ ddLCHash()

static DD_INLINE unsigned int ddLCHash ( DdNodePtr key,
unsigned int  keysize,
int  shift 
)
static

Function********************************************************************

Synopsis [Computes the hash value for a local cache.]

Description [Computes the hash value for a local cache. Returns the bucket index.]

SideEffects [None]

SeeAlso []

Definition at line 12304 of file cuddInt.c.

12308 {
12309  unsigned int val = (unsigned int) (ptrint) key[0] * DD_P2;
12310  unsigned int i;
12311 
12312  for (i = 1; i < keysize; i++) {
12313  val = val * DD_P1 + (int) (ptrint) key[i];
12314  }
12315 
12316  return(val >> shift);
12317 
12318 } /* end of ddLCHash */
int ptrint
Definition: cuddInt.h:249
#define DD_P2
Definition: cuddInt.h:157
#define DD_P1
Definition: cuddInt.h:156

◆ ddLeavesInt()

static int ddLeavesInt ( DdNode n)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_CountLeaves.]

Description [Performs the recursive step of Cudd_CountLeaves. Returns the number of leaves in the DD rooted at n.]

SideEffects [None]

SeeAlso [Cudd_CountLeaves]

Definition at line 23852 of file cuddInt.c.

23854 {
23855 int tval, eval;
23856 
23857 if (Cudd_IsComplement(n->next)) {
23858 return(0);
23859 }
23860 n->next = Cudd_Not(n->next);
23861 if (cuddIsConstant(n)) {
23862 return(1);
23863 }
23864 tval = ddLeavesInt(cuddT(n));
23865 eval = ddLeavesInt(Cudd_Regular(cuddE(n)));
23866 return(tval + eval);
23867 
23868 } /* end of ddLeavesInt */
static int ddLeavesInt(DdNode *n)
Definition: cuddInt.c:23852
#define Cudd_Not(node)
Definition: cudd.h:343
#define Cudd_Regular(node)
Definition: cudd.h:373
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode * next
Definition: cudd.h:267
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddE(node)
Definition: cuddInt.h:625

◆ ddLinearAndSiftingAux()

static int ddLinearAndSiftingAux ( DdManager table,
int  x,
int  xLow,
int  xHigh 
)
static

Function********************************************************************

Synopsis [Given xLow <= x <= xHigh moves x up and down between the boundaries.]

Description [Given xLow <= x <= xHigh moves x up and down between the boundaries. At each step a linear transformation is tried, and, if it decreases the size of the DD, it is accepted. Finds the best position and does the required changes. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 13410 of file cuddInt.c.

13415 {
13416 
13417  Move *move;
13418  Move *moveUp; /* list of up moves */
13419  Move *moveDown; /* list of down moves */
13420  int initialSize;
13421  int result;
13422 
13423  initialSize = table->keys - table->isolated;
13424 
13425  moveDown = NULL;
13426  moveUp = NULL;
13427 
13428  if (x == xLow) {
13429  moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL);
13430  /* At this point x --> xHigh unless bounding occurred. */
13431  if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
13432  /* Move backward and stop at best position. */
13433  result = ddLinearAndSiftingBackward(table,initialSize,moveDown);
13434  if (!result) goto ddLinearAndSiftingAuxOutOfMem;
13435 
13436  } else if (x == xHigh) {
13437  moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL);
13438  /* At this point x --> xLow unless bounding occurred. */
13439  if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
13440  /* Move backward and stop at best position. */
13441  result = ddLinearAndSiftingBackward(table,initialSize,moveUp);
13442  if (!result) goto ddLinearAndSiftingAuxOutOfMem;
13443 
13444  } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */
13445  moveDown = ddLinearAndSiftingDown(table,x,xHigh,NULL);
13446  /* At this point x --> xHigh unless bounding occurred. */
13447  if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
13448  moveUp = ddUndoMoves(table,moveDown);
13449 #ifdef DD_DEBUG
13450  assert(moveUp == NULL || moveUp->x == x);
13451 #endif
13452  moveUp = ddLinearAndSiftingUp(table,x,xLow,moveUp);
13453  if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
13454  /* Move backward and stop at best position. */
13455  result = ddLinearAndSiftingBackward(table,initialSize,moveUp);
13456  if (!result) goto ddLinearAndSiftingAuxOutOfMem;
13457 
13458  } else { /* must go up first: shorter */
13459  moveUp = ddLinearAndSiftingUp(table,x,xLow,NULL);
13460  /* At this point x --> xLow unless bounding occurred. */
13461  if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
13462  moveDown = ddUndoMoves(table,moveUp);
13463 #ifdef DD_DEBUG
13464  assert(moveDown == NULL || moveDown->y == x);
13465 #endif
13466  moveDown = ddLinearAndSiftingDown(table,x,xHigh,moveDown);
13467  if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddLinearAndSiftingAuxOutOfMem;
13468  /* Move backward and stop at best position. */
13469  result = ddLinearAndSiftingBackward(table,initialSize,moveDown);
13470  if (!result) goto ddLinearAndSiftingAuxOutOfMem;
13471  }
13472 
13473  while (moveDown != NULL) {
13474  move = moveDown->next;
13475  cuddDeallocMove(table, moveDown);
13476  moveDown = move;
13477  }
13478  while (moveUp != NULL) {
13479  move = moveUp->next;
13480  cuddDeallocMove(table, moveUp);
13481  moveUp = move;
13482  }
13483 
13484  return(1);
13485 
13486  ddLinearAndSiftingAuxOutOfMem:
13487  while (moveDown != NULL) {
13488  move = moveDown->next;
13489  cuddDeallocMove(table, moveDown);
13490  moveDown = move;
13491  }
13492  while (moveUp != NULL) {
13493  move = moveUp->next;
13494  cuddDeallocMove(table, moveUp);
13495  moveUp = move;
13496  }
13497 
13498  return(0);
13499 
13500 } /* end of ddLinearAndSiftingAux */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
static Move * ddUndoMoves(DdManager *table, Move *moves)
Definition: cuddInt.c:13798
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
static int ddLinearAndSiftingBackward(DdManager *table, int size, Move *moves)
Definition: cuddInt.c:13752
static Move * ddLinearAndSiftingUp(DdManager *table, int y, int xLow, Move *prevMoves)
Definition: cuddInt.c:13516
unsigned int keys
Definition: cuddInt.h:353
static Move * ddLinearAndSiftingDown(DdManager *table, int x, int xHigh, Move *prevMoves)
Definition: cuddInt.c:13639
DdHalfWord x
Definition: cuddInt.h:470
static int result
Definition: cuddInt.c:7466
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int isolated
Definition: cuddInt.h:368

◆ ddLinearAndSiftingBackward()

static int ddLinearAndSiftingBackward ( DdManager table,
int  size,
Move moves 
)
static

Function********************************************************************

Synopsis [Given a set of moves, returns the DD heap to the order giving the minimum size.]

Description [Given a set of moves, returns the DD heap to the position giving the minimum size. In case of ties, returns to the closest position giving the minimum size. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 13752 of file cuddInt.c.

13756 {
13757  Move *move;
13758  int res;
13759 
13760  for (move = moves; move != NULL; move = move->next) {
13761  if (move->size < size) {
13762  size = move->size;
13763  }
13764  }
13765 
13766  for (move = moves; move != NULL; move = move->next) {
13767  if (move->size == size) return(1);
13768  if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) {
13769  res = cuddLinearInPlace(table,(int)move->x,(int)move->y);
13770  if (!res) return(0);
13771  }
13772  res = cuddSwapInPlace(table,(int)move->x,(int)move->y);
13773  if (!res) return(0);
13774  if (move->flags == CUDD_INVERSE_TRANSFORM_MOVE) {
13775  res = cuddLinearInPlace(table,(int)move->x,(int)move->y);
13776  if (!res) return(0);
13777  }
13778  }
13779 
13780  return(1);
13781 
13782 } /* end of ddLinearAndSiftingBackward */
Definition: cuddInt.h:469
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:12874
#define CUDD_INVERSE_TRANSFORM_MOVE
Definition: cuddInt.c:28544
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddInt.c:28543
int size
Definition: cuddInt.h:473

◆ ddLinearAndSiftingDown()

static Move * ddLinearAndSiftingDown ( DdManager table,
int  x,
int  xHigh,
Move prevMoves 
)
static

Function********************************************************************

Synopsis [Sifts a variable down and applies linear transformations.]

Description [Sifts a variable down and applies linear transformations. Moves x down until either it reaches the bound (xHigh) or the size of the DD heap increases too much. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

Definition at line 13639 of file cuddInt.c.

13644 {
13645  Move *moves;
13646  Move *move;
13647  int y;
13648  int size, newsize;
13649  int R; /* upper bound on node decrease */
13650  int limitSize;
13651  int xindex, yindex;
13652  int isolated;
13653 #ifdef DD_DEBUG
13654  int checkR;
13655  int z;
13656  int zindex;
13657 #endif
13658 
13659  moves = prevMoves;
13660  /* Initialize R */
13661  xindex = table->invperm[x];
13662  limitSize = size = table->keys - table->isolated;
13663  R = 0;
13664  for (y = xHigh; y > x; y--) {
13665  yindex = table->invperm[y];
13666  if (cuddTestInteract(table,xindex,yindex)) {
13667  isolated = table->vars[yindex]->ref == 1;
13668  R += table->subtables[y].keys - isolated;
13669  }
13670  }
13671 
13672  y = cuddNextHigh(table,x);
13673  while (y <= xHigh && size - R < limitSize) {
13674 #ifdef DD_DEBUG
13675  checkR = 0;
13676  for (z = xHigh; z > x; z--) {
13677  zindex = table->invperm[z];
13678  if (cuddTestInteract(table,xindex,zindex)) {
13679  isolated = table->vars[zindex]->ref == 1;
13680  checkR += table->subtables[z].keys - isolated;
13681  }
13682  }
13683  if (R != checkR) {
13684  (void) fprintf(table->out, "checkR(%d) != R(%d)\n",checkR,R);
13685  }
13686 #endif
13687  /* Update upper bound on node decrease. */
13688  yindex = table->invperm[y];
13689  if (cuddTestInteract(table,xindex,yindex)) {
13690  isolated = table->vars[yindex]->ref == 1;
13691  R -= table->subtables[y].keys - isolated;
13692  }
13693  size = cuddSwapInPlace(table,x,y);
13694  if (size == 0) goto ddLinearAndSiftingDownOutOfMem;
13695  newsize = cuddLinearInPlace(table,x,y);
13696  if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem;
13697  move = (Move *) cuddDynamicAllocNode(table);
13698  if (move == NULL) goto ddLinearAndSiftingDownOutOfMem;
13699  move->x = x;
13700  move->y = y;
13701  move->next = moves;
13702  moves = move;
13703  move->flags = CUDD_SWAP_MOVE;
13704  if (newsize >= size) {
13705  /* Undo transformation. The transformation we apply is
13706  ** its own inverse. Hence, we just apply the transformation
13707  ** again.
13708  */
13709  newsize = cuddLinearInPlace(table,x,y);
13710  if (newsize == 0) goto ddLinearAndSiftingDownOutOfMem;
13711  if (newsize != size) {
13712  (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize);
13713  }
13714  } else if (cuddTestInteract(table,xindex,yindex)) {
13715  size = newsize;
13717  cuddUpdateInteractionMatrix(table,xindex,yindex);
13718  }
13719  move->size = size;
13720  if ((double) size > (double) limitSize * table->maxGrowth) break;
13721  if (size < limitSize) limitSize = size;
13722  x = y;
13723  y = cuddNextHigh(table,x);
13724  }
13725  return(moves);
13726 
13727  ddLinearAndSiftingDownOutOfMem:
13728  while (moves != NULL) {
13729  move = moves->next;
13730  cuddDeallocMove(table, moves);
13731  moves = move;
13732  }
13733  return((Move *) CUDD_OUT_OF_MEM);
13734 
13735 } /* end of ddLinearAndSiftingDown */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
void cuddUpdateInteractionMatrix(DdManager *table, int xindex, int yindex)
Definition: cuddInt.c:13228
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define CUDD_SWAP_MOVE
Definition: cuddInt.c:28542
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:12874
DdHalfWord y
Definition: cuddInt.h:471
DdNode ** vars
Definition: cuddInt.h:373
struct Move * next
Definition: cuddInt.h:474
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddInt.c:28543
int size
Definition: cuddInt.h:473

◆ ddLinearAndSiftingUp()

static Move * ddLinearAndSiftingUp ( DdManager table,
int  y,
int  xLow,
Move prevMoves 
)
static

Function********************************************************************

Synopsis [Sifts a variable up and applies linear transformations.]

Description [Sifts a variable up and applies linear transformations. Moves y up until either it reaches the bound (xLow) or the size of the DD heap increases too much. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

Definition at line 13516 of file cuddInt.c.

13521 {
13522  Move *moves;
13523  Move *move;
13524  int x;
13525  int size, newsize;
13526  int limitSize;
13527  int xindex, yindex;
13528  int isolated;
13529  int L; /* lower bound on DD size */
13530 #ifdef DD_DEBUG
13531  int checkL;
13532  int z;
13533  int zindex;
13534 #endif
13535 
13536  moves = prevMoves;
13537  yindex = table->invperm[y];
13538 
13539  /* Initialize the lower bound.
13540  ** The part of the DD below y will not change.
13541  ** The part of the DD above y that does not interact with y will not
13542  ** change. The rest may vanish in the best case, except for
13543  ** the nodes at level xLow, which will not vanish, regardless.
13544  */
13545  limitSize = L = table->keys - table->isolated;
13546  for (x = xLow + 1; x < y; x++) {
13547  xindex = table->invperm[x];
13548  if (cuddTestInteract(table,xindex,yindex)) {
13549  isolated = table->vars[xindex]->ref == 1;
13550  L -= table->subtables[x].keys - isolated;
13551  }
13552  }
13553  isolated = table->vars[yindex]->ref == 1;
13554  L -= table->subtables[y].keys - isolated;
13555 
13556  x = cuddNextLow(table,y);
13557  while (x >= xLow && L <= limitSize) {
13558  xindex = table->invperm[x];
13559 #ifdef DD_DEBUG
13560  checkL = table->keys - table->isolated;
13561  for (z = xLow + 1; z < y; z++) {
13562  zindex = table->invperm[z];
13563  if (cuddTestInteract(table,zindex,yindex)) {
13564  isolated = table->vars[zindex]->ref == 1;
13565  checkL -= table->subtables[z].keys - isolated;
13566  }
13567  }
13568  isolated = table->vars[yindex]->ref == 1;
13569  checkL -= table->subtables[y].keys - isolated;
13570  if (L != checkL) {
13571  (void) fprintf(table->out, "checkL(%d) != L(%d)\n",checkL,L);
13572  }
13573 #endif
13574  size = cuddSwapInPlace(table,x,y);
13575  if (size == 0) goto ddLinearAndSiftingUpOutOfMem;
13576  newsize = cuddLinearInPlace(table,x,y);
13577  if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem;
13578  move = (Move *) cuddDynamicAllocNode(table);
13579  if (move == NULL) goto ddLinearAndSiftingUpOutOfMem;
13580  move->x = x;
13581  move->y = y;
13582  move->next = moves;
13583  moves = move;
13584  move->flags = CUDD_SWAP_MOVE;
13585  if (newsize >= size) {
13586  /* Undo transformation. The transformation we apply is
13587  ** its own inverse. Hence, we just apply the transformation
13588  ** again.
13589  */
13590  newsize = cuddLinearInPlace(table,x,y);
13591  if (newsize == 0) goto ddLinearAndSiftingUpOutOfMem;
13592 #ifdef DD_DEBUG
13593  if (newsize != size) {
13594  (void) fprintf(table->out,"Change in size after identity transformation! From %d to %d\n",size,newsize);
13595  }
13596 #endif
13597  } else if (cuddTestInteract(table,xindex,yindex)) {
13598  size = newsize;
13600  cuddUpdateInteractionMatrix(table,xindex,yindex);
13601  }
13602  move->size = size;
13603  /* Update the lower bound. */
13604  if (cuddTestInteract(table,xindex,yindex)) {
13605  isolated = table->vars[xindex]->ref == 1;
13606  L += table->subtables[y].keys - isolated;
13607  }
13608  if ((double) size > (double) limitSize * table->maxGrowth) break;
13609  if (size < limitSize) limitSize = size;
13610  y = x;
13611  x = cuddNextLow(table,y);
13612  }
13613  return(moves);
13614 
13615  ddLinearAndSiftingUpOutOfMem:
13616  while (moves != NULL) {
13617  move = moves->next;
13618  cuddDeallocMove(table, moves);
13619  moves = move;
13620  }
13621  return((Move *) CUDD_OUT_OF_MEM);
13622 
13623 } /* end of ddLinearAndSiftingUp */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
void cuddUpdateInteractionMatrix(DdManager *table, int xindex, int yindex)
Definition: cuddInt.c:13228
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define CUDD_SWAP_MOVE
Definition: cuddInt.c:28542
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:12874
DdHalfWord y
Definition: cuddInt.h:471
DdNode ** vars
Definition: cuddInt.h:373
struct Move * next
Definition: cuddInt.h:474
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddInt.c:28543
int size
Definition: cuddInt.h:473

◆ ddLinearUniqueCompare()

static int ddLinearUniqueCompare ( int *  ptrX,
int *  ptrY 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Comparison function used by qsort.]

Description [Comparison function used by qsort to order the variables according to the number of keys in the subtables. Returns the difference in number of keys between the two variables being compared.]

SideEffects [None]

Definition at line 13382 of file cuddInt.c.

13385 {
13386 #if 0
13387  if (entry[*ptrY] == entry[*ptrX]) {
13388  return((*ptrX) - (*ptrY));
13389  }
13390 #endif
13391  return(entry[*ptrY] - entry[*ptrX]);
13392 
13393 } /* end of ddLinearUniqueCompare */
static int * entry
Definition: cuddInt.c:8422

◆ ddMergeGroups()

static void ddMergeGroups ( DdManager table,
MtrNode treenode,
int  low,
int  high 
)
static

Function********************************************************************

Synopsis [Merges groups in the DD table.]

Description [Creates a single group from low to high and adjusts the index field of the tree node.]

SideEffects [None]

Definition at line 10016 of file cuddInt.c.

10021 {
10022  int i;
10023  MtrNode *auxnode;
10024  int saveindex;
10025  int newindex;
10026 
10027  /* Merge all variables from low to high in one group, unless
10028  ** this is the topmost group. In such a case we do not merge lest
10029  ** we lose the symmetry information. */
10030  if (treenode != table->tree) {
10031  for (i = low; i < high; i++)
10032  table->subtables[i].next = i+1;
10033  table->subtables[high].next = low;
10034  }
10035 
10036  /* Adjust the index fields of the tree nodes. If a node is the
10037  ** first child of its parent, then the parent may also need adjustment. */
10038  saveindex = treenode->index;
10039  newindex = table->invperm[low];
10040  auxnode = treenode;
10041  do {
10042  auxnode->index = newindex;
10043  if (auxnode->parent == NULL ||
10044  (int) auxnode->parent->index != saveindex)
10045  break;
10046  auxnode = auxnode->parent;
10047  } while (1);
10048  return;
10049 
10050 } /* end of ddMergeGroups */
DdSubtable * subtables
Definition: cuddInt.h:349
struct MtrNode * parent
Definition: mtr.h:131
MtrNode * tree
Definition: cuddInt.h:408
MtrHalfWord index
Definition: mtr.h:130
Definition: mtr.h:126
unsigned int next
Definition: cuddInt.h:317
int * invperm
Definition: cuddInt.h:371

◆ ddNoCheck()

static int ddNoCheck ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [Pretends to check two variables for aggregation.]

Description [Pretends to check two variables for aggregation. Always returns 0.]

SideEffects [None]

Definition at line 10098 of file cuddInt.c.

10102 {
10103  return(0);
10104 
10105 } /* end of ddNoCheck */

◆ ddPatchTree()

static void ddPatchTree ( DdManager dd,
MtrNode treenode 
)
static

Function********************************************************************

Synopsis [Fixes a variable tree after the insertion of new subtables.]

Description [Fixes a variable tree after the insertion of new subtables. After such an insertion, the low fields of the tree below the insertion point are inconsistent.]

SideEffects [None]

SeeAlso []

Definition at line 21899 of file cuddInt.c.

21902 {
21903 MtrNode *auxnode = treenode;
21904 
21905 while (auxnode != NULL) {
21906 auxnode->low = dd->perm[auxnode->index];
21907 if (auxnode->child != NULL) {
21908 ddPatchTree(dd, auxnode->child);
21909 }
21910 auxnode = auxnode->younger;
21911 }
21912 
21913 return;
21914 
21915 } /* end of ddPatchTree */
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord index
Definition: mtr.h:130
static void ddPatchTree(DdManager *dd, MtrNode *treenode)
Definition: cuddInt.c:21899
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
struct MtrNode * child
Definition: mtr.h:132
int * perm
Definition: cuddInt.h:369

◆ ddPermuteWindow3()

static int ddPermuteWindow3 ( DdManager table,
int  x 
)
static

Function********************************************************************

Synopsis [Tries all the permutations of the three variables between x and x+2 and retains the best.]

Description [Tries all the permutations of the three variables between x and x+2 and retains the best. Assumes that no dead nodes are present. Returns the index of the best permutation (1-6) in case of success; 0 otherwise.Assumes that no dead nodes are present. Returns the index of the best permutation (1-6) in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 24342 of file cuddInt.c.

24345 {
24346 int y,z;
24347 int size,sizeNew;
24348 int best;
24349 
24350 #ifdef DD_DEBUG
24351 assert(table->dead == 0);
24352 assert(x+2 < table->size);
24353 #endif
24354 
24355 size = table->keys - table->isolated;
24356 y = x+1; z = y+1;
24357 
24358 /* The permutation pattern is:
24359 ** (x,y)(y,z)
24360 ** repeated three times to get all 3! = 6 permutations.
24361 */
24362 #define ABC 1
24363 best = ABC;
24364 
24365 #define BAC 2
24366 sizeNew = cuddSwapInPlace(table,x,y);
24367 if (sizeNew < size) {
24368 if (sizeNew == 0) return(0);
24369 best = BAC;
24370 size = sizeNew;
24371 }
24372 #define BCA 3
24373 sizeNew = cuddSwapInPlace(table,y,z);
24374 if (sizeNew < size) {
24375 if (sizeNew == 0) return(0);
24376 best = BCA;
24377 size = sizeNew;
24378 }
24379 #define CBA 4
24380 sizeNew = cuddSwapInPlace(table,x,y);
24381 if (sizeNew < size) {
24382 if (sizeNew == 0) return(0);
24383 best = CBA;
24384 size = sizeNew;
24385 }
24386 #define CAB 5
24387 sizeNew = cuddSwapInPlace(table,y,z);
24388 if (sizeNew < size) {
24389 if (sizeNew == 0) return(0);
24390 best = CAB;
24391 size = sizeNew;
24392 }
24393 #define ACB 6
24394 sizeNew = cuddSwapInPlace(table,x,y);
24395 if (sizeNew < size) {
24396 if (sizeNew == 0) return(0);
24397 best = ACB;
24398 size = sizeNew;
24399 }
24400 
24401 /* Now take the shortest route to the best permuytation.
24402 ** The initial permutation is ACB.
24403 */
24404 switch(best) {
24405 case BCA: if (!cuddSwapInPlace(table,y,z)) return(0);
24406 case CBA: if (!cuddSwapInPlace(table,x,y)) return(0);
24407 case ABC: if (!cuddSwapInPlace(table,y,z)) return(0);
24408 case ACB: break;
24409 case BAC: if (!cuddSwapInPlace(table,y,z)) return(0);
24410 case CAB: if (!cuddSwapInPlace(table,x,y)) return(0);
24411 break;
24412 default: return(0);
24413 }
24414 
24415 #ifdef DD_DEBUG
24416 assert(table->keys - table->isolated == (unsigned) size);
24417 #endif
24418 
24419 return(best);
24420 
24421 } /* end of ddPermuteWindow3 */
#define BCA
#define CAB
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
#define ABC
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
#define CBA
unsigned int dead
Definition: cuddInt.h:355
unsigned int keys
Definition: cuddInt.h:353
#define ACB
#define BAC
int isolated
Definition: cuddInt.h:368

◆ ddPermuteWindow4()

static int ddPermuteWindow4 ( DdManager table,
int  w 
)
static

Function********************************************************************

Synopsis [Tries all the permutations of the four variables between w and w+3 and retains the best.]

Description [Tries all the permutations of the four variables between w and w+3 and retains the best. Assumes that no dead nodes are present. Returns the index of the best permutation (1-24) in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 24582 of file cuddInt.c.

24585 {
24586 int x,y,z;
24587 int size,sizeNew;
24588 int best;
24589 
24590 #ifdef DD_DEBUG
24591 assert(table->dead == 0);
24592 assert(w+3 < table->size);
24593 #endif
24594 
24595 size = table->keys - table->isolated;
24596 x = w+1; y = x+1; z = y+1;
24597 
24598 /* The permutation pattern is:
24599  * (w,x)(y,z)(w,x)(x,y)
24600  * (y,z)(w,x)(y,z)(x,y)
24601  * repeated three times to get all 4! = 24 permutations.
24602  * This gives a hamiltonian circuit of Cayley's graph.
24603  * The codes to the permutation are assigned in topological order.
24604  * The permutations at lower distance from the final permutation are
24605  * assigned lower codes. This way we can choose, between
24606  * permutations that give the same size, one that requires the minimum
24607  * number of swaps from the final permutation of the hamiltonian circuit.
24608  * There is an exception to this rule: ABCD is given Code 1, to
24609  * avoid oscillation when convergence is sought.
24610  */
24611 #define ABCD 1
24612 best = ABCD;
24613 
24614 #define BACD 7
24615 sizeNew = cuddSwapInPlace(table,w,x);
24616 if (sizeNew < size) {
24617 if (sizeNew == 0) return(0);
24618 best = BACD;
24619 size = sizeNew;
24620 }
24621 #define BADC 13
24622 sizeNew = cuddSwapInPlace(table,y,z);
24623 if (sizeNew < size) {
24624 if (sizeNew == 0) return(0);
24625 best = BADC;
24626 size = sizeNew;
24627 }
24628 #define ABDC 8
24629 sizeNew = cuddSwapInPlace(table,w,x);
24630 if (sizeNew < size || (sizeNew == size && ABDC < best)) {
24631 if (sizeNew == 0) return(0);
24632 best = ABDC;
24633 size = sizeNew;
24634 }
24635 #define ADBC 14
24636 sizeNew = cuddSwapInPlace(table,x,y);
24637 if (sizeNew < size) {
24638 if (sizeNew == 0) return(0);
24639 best = ADBC;
24640 size = sizeNew;
24641 }
24642 #define ADCB 9
24643 sizeNew = cuddSwapInPlace(table,y,z);
24644 if (sizeNew < size || (sizeNew == size && ADCB < best)) {
24645 if (sizeNew == 0) return(0);
24646 best = ADCB;
24647 size = sizeNew;
24648 }
24649 #define DACB 15
24650 sizeNew = cuddSwapInPlace(table,w,x);
24651 if (sizeNew < size) {
24652 if (sizeNew == 0) return(0);
24653 best = DACB;
24654 size = sizeNew;
24655 }
24656 #define DABC 20
24657 sizeNew = cuddSwapInPlace(table,y,z);
24658 if (sizeNew < size) {
24659 if (sizeNew == 0) return(0);
24660 best = DABC;
24661 size = sizeNew;
24662 }
24663 #define DBAC 23
24664 sizeNew = cuddSwapInPlace(table,x,y);
24665 if (sizeNew < size) {
24666 if (sizeNew == 0) return(0);
24667 best = DBAC;
24668 size = sizeNew;
24669 }
24670 #define BDAC 19
24671 sizeNew = cuddSwapInPlace(table,w,x);
24672 if (sizeNew < size || (sizeNew == size && BDAC < best)) {
24673 if (sizeNew == 0) return(0);
24674 best = BDAC;
24675 size = sizeNew;
24676 }
24677 #define BDCA 21
24678 sizeNew = cuddSwapInPlace(table,y,z);
24679 if (sizeNew < size || (sizeNew == size && BDCA < best)) {
24680 if (sizeNew == 0) return(0);
24681 best = BDCA;
24682 size = sizeNew;
24683 }
24684 #define DBCA 24
24685 sizeNew = cuddSwapInPlace(table,w,x);
24686 if (sizeNew < size) {
24687 if (sizeNew == 0) return(0);
24688 best = DBCA;
24689 size = sizeNew;
24690 }
24691 #define DCBA 22
24692 sizeNew = cuddSwapInPlace(table,x,y);
24693 if (sizeNew < size || (sizeNew == size && DCBA < best)) {
24694 if (sizeNew == 0) return(0);
24695 best = DCBA;
24696 size = sizeNew;
24697 }
24698 #define DCAB 18
24699 sizeNew = cuddSwapInPlace(table,y,z);
24700 if (sizeNew < size || (sizeNew == size && DCAB < best)) {
24701 if (sizeNew == 0) return(0);
24702 best = DCAB;
24703 size = sizeNew;
24704 }
24705 #define CDAB 12
24706 sizeNew = cuddSwapInPlace(table,w,x);
24707 if (sizeNew < size || (sizeNew == size && CDAB < best)) {
24708 if (sizeNew == 0) return(0);
24709 best = CDAB;
24710 size = sizeNew;
24711 }
24712 #define CDBA 17
24713 sizeNew = cuddSwapInPlace(table,y,z);
24714 if (sizeNew < size || (sizeNew == size && CDBA < best)) {
24715 if (sizeNew == 0) return(0);
24716 best = CDBA;
24717 size = sizeNew;
24718 }
24719 #define CBDA 11
24720 sizeNew = cuddSwapInPlace(table,x,y);
24721 if (sizeNew < size || (sizeNew == size && CBDA < best)) {
24722 if (sizeNew == 0) return(0);
24723 best = CBDA;
24724 size = sizeNew;
24725 }
24726 #define BCDA 16
24727 sizeNew = cuddSwapInPlace(table,w,x);
24728 if (sizeNew < size || (sizeNew == size && BCDA < best)) {
24729 if (sizeNew == 0) return(0);
24730 best = BCDA;
24731 size = sizeNew;
24732 }
24733 #define BCAD 10
24734 sizeNew = cuddSwapInPlace(table,y,z);
24735 if (sizeNew < size || (sizeNew == size && BCAD < best)) {
24736 if (sizeNew == 0) return(0);
24737 best = BCAD;
24738 size = sizeNew;
24739 }
24740 #define CBAD 5
24741 sizeNew = cuddSwapInPlace(table,w,x);
24742 if (sizeNew < size || (sizeNew == size && CBAD < best)) {
24743 if (sizeNew == 0) return(0);
24744 best = CBAD;
24745 size = sizeNew;
24746 }
24747 #define CABD 3
24748 sizeNew = cuddSwapInPlace(table,x,y);
24749 if (sizeNew < size || (sizeNew == size && CABD < best)) {
24750 if (sizeNew == 0) return(0);
24751 best = CABD;
24752 size = sizeNew;
24753 }
24754 #define CADB 6
24755 sizeNew = cuddSwapInPlace(table,y,z);
24756 if (sizeNew < size || (sizeNew == size && CADB < best)) {
24757 if (sizeNew == 0) return(0);
24758 best = CADB;
24759 size = sizeNew;
24760 }
24761 #define ACDB 4
24762 sizeNew = cuddSwapInPlace(table,w,x);
24763 if (sizeNew < size || (sizeNew == size && ACDB < best)) {
24764 if (sizeNew == 0) return(0);
24765 best = ACDB;
24766 size = sizeNew;
24767 }
24768 #define ACBD 2
24769 sizeNew = cuddSwapInPlace(table,y,z);
24770 if (sizeNew < size || (sizeNew == size && ACBD < best)) {
24771 if (sizeNew == 0) return(0);
24772 best = ACBD;
24773 size = sizeNew;
24774 }
24775 
24776 /* Now take the shortest route to the best permutation.
24777 ** The initial permutation is ACBD.
24778 */
24779 switch(best) {
24780 case DBCA: if (!cuddSwapInPlace(table,y,z)) return(0);
24781 case BDCA: if (!cuddSwapInPlace(table,x,y)) return(0);
24782 case CDBA: if (!cuddSwapInPlace(table,w,x)) return(0);
24783 case ADBC: if (!cuddSwapInPlace(table,y,z)) return(0);
24784 case ABDC: if (!cuddSwapInPlace(table,x,y)) return(0);
24785 case ACDB: if (!cuddSwapInPlace(table,y,z)) return(0);
24786 case ACBD: break;
24787 case DCBA: if (!cuddSwapInPlace(table,y,z)) return(0);
24788 case BCDA: if (!cuddSwapInPlace(table,x,y)) return(0);
24789 case CBDA: if (!cuddSwapInPlace(table,w,x)) return(0);
24790 if (!cuddSwapInPlace(table,x,y)) return(0);
24791 if (!cuddSwapInPlace(table,y,z)) return(0);
24792 break;
24793 case DBAC: if (!cuddSwapInPlace(table,x,y)) return(0);
24794 case DCAB: if (!cuddSwapInPlace(table,w,x)) return(0);
24795 case DACB: if (!cuddSwapInPlace(table,y,z)) return(0);
24796 case BACD: if (!cuddSwapInPlace(table,x,y)) return(0);
24797 case CABD: if (!cuddSwapInPlace(table,w,x)) return(0);
24798 break;
24799 case DABC: if (!cuddSwapInPlace(table,y,z)) return(0);
24800 case BADC: if (!cuddSwapInPlace(table,x,y)) return(0);
24801 case CADB: if (!cuddSwapInPlace(table,w,x)) return(0);
24802 if (!cuddSwapInPlace(table,y,z)) return(0);
24803 break;
24804 case BDAC: if (!cuddSwapInPlace(table,x,y)) return(0);
24805 case CDAB: if (!cuddSwapInPlace(table,w,x)) return(0);
24806 case ADCB: if (!cuddSwapInPlace(table,y,z)) return(0);
24807 case ABCD: if (!cuddSwapInPlace(table,x,y)) return(0);
24808 break;
24809 case BCAD: if (!cuddSwapInPlace(table,x,y)) return(0);
24810 case CBAD: if (!cuddSwapInPlace(table,w,x)) return(0);
24811 if (!cuddSwapInPlace(table,x,y)) return(0);
24812 break;
24813 default: return(0);
24814 }
24815 
24816 #ifdef DD_DEBUG
24817 assert(table->keys - table->isolated == (unsigned) size);
24818 #endif
24819 
24820 return(best);
24821 
24822 } /* end of ddPermuteWindow4 */
#define BDCA
#define DCBA
#define ACBD
#define BDAC
#define CADB
#define DBAC
#define ADCB
#define assert(ex)
Definition: util.h:141
#define CBDA
int size
Definition: cuddInt.h:345
#define DABC
#define BCDA
#define ABCD
#define ADBC
#define DCAB
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
#define DBCA
#define CABD
unsigned int dead
Definition: cuddInt.h:355
#define BACD
#define CDAB
unsigned int keys
Definition: cuddInt.h:353
#define BADC
#define DACB
#define BCAD
#define ACDB
#define ABDC
#define CBAD
#define CDBA
int isolated
Definition: cuddInt.h:368

◆ ddPickArbitraryMinterms()

static int ddPickArbitraryMinterms ( DdManager dd,
DdNode node,
int  nvars,
int  nminterms,
char **  string 
)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_bddPickArbitraryMinterms.]

Description [Performs the recursive step of Cudd_bddPickArbitraryMinterms. Returns 1 if successful; 0 otherwise.]

SideEffects [none]

SeeAlso [Cudd_bddPickArbitraryMinterms]

Definition at line 23884 of file cuddInt.c.

23890 {
23891 DdNode *N, *T, *E;
23892 DdNode *one, *bzero;
23893 int i, t, result;
23894 double min1, min2;
23895 
23896 if (string == NULL || node == NULL) return(0);
23897 
23898 /* The constant 0 function has no on-set cubes. */
23899 one = DD_ONE(dd);
23900 bzero = Cudd_Not(one);
23901 if (nminterms == 0 || node == bzero) return(1);
23902 if (node == one) {
23903 return(1);
23904 }
23905 
23906 N = Cudd_Regular(node);
23907 T = cuddT(N); E = cuddE(N);
23908 if (Cudd_IsComplement(node)) {
23909 T = Cudd_Not(T); E = Cudd_Not(E);
23910 }
23911 
23912 min1 = Cudd_CountMinterm(dd, T, nvars) / 2.0;
23913 if (min1 == (double)CUDD_OUT_OF_MEM) return(0);
23914 min2 = Cudd_CountMinterm(dd, E, nvars) / 2.0;
23915 if (min2 == (double)CUDD_OUT_OF_MEM) return(0);
23916 
23917 t = (int)((double)nminterms * min1 / (min1 + min2) + 0.5);
23918 for (i = 0; i < t; i++)
23919 string[i][N->index] = '1';
23920 for (i = t; i < nminterms; i++)
23921 string[i][N->index] = '0';
23922 
23923 result = ddPickArbitraryMinterms(dd,T,nvars,t,&string[0]);
23924 if (result == 0)
23925 return(0);
23926 result = ddPickArbitraryMinterms(dd,E,nvars,nminterms-t,&string[t]);
23927 return(result);
23928 
23929 } /* end of ddPickArbitraryMinterms */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
static int ddPickArbitraryMinterms(DdManager *dd, DdNode *node, int nvars, int nminterms, char **string)
Definition: cuddInt.c:23884
double Cudd_CountMinterm(DdManager *manager, DdNode *node, int nvars)
Definition: cuddInt.c:22209
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
static int result
Definition: cuddInt.c:7466
#define cuddE(node)
Definition: cuddInt.h:625
#define DD_ONE(dd)
Definition: cuddInt.h:864

◆ ddPrintMintermAux()

static void ddPrintMintermAux ( DdManager dd,
DdNode node,
int *  list 
)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_PrintMinterm.]

Description []

SideEffects [None]

Definition at line 23199 of file cuddInt.c.

23203 {
23204 DdNode *N,*Nv,*Nnv;
23205 int i,v,index;
23206 
23207 N = Cudd_Regular(node);
23208 
23209 if (cuddIsConstant(N)) {
23210 /* Terminal case: Print one cube based on the current recursion
23211 ** path, unless we have reached the background value (ADDs) or
23212 ** the logical zero (BDDs).
23213 */
23214 if (node != background && node != zero) {
23215 for (i = 0; i < dd->size; i++) {
23216 v = list[i];
23217 if (v == 0) (void) fprintf(dd->out,"0");
23218 else if (v == 1) (void) fprintf(dd->out,"1");
23219 else (void) fprintf(dd->out,"-");
23220 }
23221 (void) fprintf(dd->out," % g\n", cuddV(node));
23222 }
23223 } else {
23224 Nv = cuddT(N);
23225 Nnv = cuddE(N);
23226 if (Cudd_IsComplement(node)) {
23227 Nv = Cudd_Not(Nv);
23228 Nnv = Cudd_Not(Nnv);
23229 }
23230 index = N->index;
23231 list[index] = 0;
23232 ddPrintMintermAux(dd,Nnv,list);
23233 list[index] = 1;
23234 ddPrintMintermAux(dd,Nv,list);
23235 list[index] = 2;
23236 }
23237 return;
23238 
23239 } /* end of ddPrintMintermAux */
static void ddPrintMintermAux(DdManager *dd, DdNode *node, int *list)
Definition: cuddInt.c:23199
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
int size
Definition: cuddInt.h:345
#define Cudd_Regular(node)
Definition: cudd.h:373
static DdNode * background
Definition: cuddInt.c:22141
#define cuddV(node)
Definition: cuddInt.h:641
#define Cudd_IsComplement(node)
Definition: cudd.h:401
FILE * out
Definition: cuddInt.h:423
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562

◆ ddRehashZdd()

static void ddRehashZdd ( DdManager unique,
int  i 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Rehashes a ZDD unique subtable.]

Description []

SideEffects [None]

SeeAlso [cuddRehash]

Definition at line 21274 of file cuddInt.c.

21277 {
21278 unsigned int slots, oldslots;
21279 int shift, oldshift;
21280 int j, pos;
21281 DdNodePtr *nodelist, *oldnodelist;
21282 DdNode *node, *next;
21283 extern DD_OOMFP MMoutOfMemory;
21284 DD_OOMFP saveHandler;
21285 
21286 if (unique->slots > unique->looseUpTo) {
21287 unique->minDead = (unsigned) (DD_GC_FRAC_LO * (double) unique->slots);
21288 #ifdef DD_VERBOSE
21289 if (unique->gcFrac == DD_GC_FRAC_HI) {
21290 (void) fprintf(unique->err,"GC fraction = %.2f\t",
21291 DD_GC_FRAC_LO);
21292 (void) fprintf(unique->err,"minDead = %d\n", unique->minDead);
21293 }
21294 #endif
21295 unique->gcFrac = DD_GC_FRAC_LO;
21296 }
21297 
21298 assert(i != CUDD_MAXINDEX);
21299 oldslots = unique->subtableZ[i].slots;
21300 oldshift = unique->subtableZ[i].shift;
21301 oldnodelist = unique->subtableZ[i].nodelist;
21302 
21303 /* Compute the new size of the subtable. Normally, we just
21304 ** double. However, after reordering, a table may be severely
21305 ** overloaded. Therefore, we iterate. */
21306 slots = oldslots;
21307 shift = oldshift;
21308 do {
21309 slots <<= 1;
21310 shift--;
21311 } while (slots * DD_MAX_SUBTABLE_DENSITY < unique->subtableZ[i].keys);
21312 
21313 saveHandler = MMoutOfMemory;
21314 MMoutOfMemory = Cudd_OutOfMem;
21315 nodelist = ALLOC(DdNodePtr, slots);
21316 MMoutOfMemory = saveHandler;
21317 if (nodelist == NULL) {
21318 (void) fprintf(unique->err,
21319 "Unable to resize ZDD subtable %d for lack of memory.\n",
21320 i);
21321 (void) cuddGarbageCollect(unique,1);
21322 for (j = 0; j < unique->sizeZ; j++) {
21323 unique->subtableZ[j].maxKeys <<= 1;
21324 }
21325 return;
21326 }
21327 unique->subtableZ[i].nodelist = nodelist;
21328 unique->subtableZ[i].slots = slots;
21329 unique->subtableZ[i].shift = shift;
21330 unique->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
21331 for (j = 0; (unsigned) j < slots; j++) {
21332 nodelist[j] = NULL;
21333 }
21334 for (j = 0; (unsigned) j < oldslots; j++) {
21335 node = oldnodelist[j];
21336 while (node != NULL) {
21337 next = node->next;
21338 pos = ddHash(cuddT(node), cuddE(node), shift);
21339 node->next = nodelist[pos];
21340 nodelist[pos] = node;
21341 node = next;
21342 }
21343 }
21344 FREE(oldnodelist);
21345 
21346 #ifdef DD_VERBOSE
21347 (void) fprintf(unique->err,
21348 "rehashing layer %d: keys %d dead %d new size %d\n",
21349 i, unique->subtableZ[i].keys,
21350 unique->subtableZ[i].dead, slots);
21351 #endif
21352 
21353 /* Update global data. */
21354 unique->memused += (slots - oldslots) * sizeof(DdNode *);
21355 unique->slots += (slots - oldslots);
21356 ddFixLimits(unique);
21357 
21358 } /* end of ddRehashZdd */
unsigned int keys
Definition: cuddInt.h:314
#define ddHash(f, g, s)
Definition: cuddInt.h:696
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
static DD_INLINE void ddFixLimits(DdManager *unique)
Definition: cuddInt.c:21624
#define assert(ex)
Definition: util.h:141
double gcFrac
Definition: cuddInt.h:359
unsigned int slots
Definition: cuddInt.h:352
FILE * err
Definition: cuddInt.h:424
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddInt.c:20120
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
void(* DD_OOMFP)(long)
Definition: cudd.h:300
#define DD_GC_FRAC_HI
Definition: cuddInt.h:135
#define ALLOC(type, num)
Definition: util.h:76
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:267
#define DD_GC_FRAC_LO
Definition: cuddInt.h:134
unsigned int maxKeys
Definition: cuddInt.h:315
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
void(* MMoutOfMemory)(long)
Definition: util.c:105
unsigned long memused
Definition: cuddInt.h:429
int sizeZ
Definition: cuddInt.h:346
unsigned int looseUpTo
Definition: cuddInt.h:361
unsigned int slots
Definition: cuddInt.h:313
#define CUDD_MAXINDEX
Definition: cudd.h:102
#define cuddE(node)
Definition: cuddInt.h:625
void Cudd_OutOfMem(long size)
Definition: cuddInt.c:22982
int shift
Definition: cuddInt.h:312
unsigned int minDead
Definition: cuddInt.h:358
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ ddReorderChildren()

static int ddReorderChildren ( DdManager table,
MtrNode treenode,
Cudd_ReorderingType  method 
)
static

Function********************************************************************

Synopsis [Reorders the children of a group tree node according to the options.]

Description [Reorders the children of a group tree node according to the options. After reordering puts all the variables in the group and/or its descendents in a single group. This allows hierarchical reordering. If the variables in the group do not exist yet, simply does nothing. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 8689 of file cuddInt.c.

8693 {
8694  int lower;
8695  int upper;
8696  int result;
8697  unsigned int initialSize;
8698 
8699  ddFindNodeHiLo(table,treenode,&lower,&upper);
8700  /* If upper == -1 these variables do not exist yet. */
8701  if (upper == -1)
8702  return(1);
8703 
8704  if (treenode->flags == MTR_FIXED) {
8705  result = 1;
8706  } else {
8707 #ifdef DD_STATS
8708  (void) fprintf(table->out," ");
8709 #endif
8710  switch (method) {
8711  case CUDD_REORDER_RANDOM:
8713  result = cuddSwapping(table,lower,upper,method);
8714  break;
8715  case CUDD_REORDER_SIFT:
8716  result = cuddSifting(table,lower,upper);
8717  break;
8719  do {
8720  initialSize = table->keys - table->isolated;
8721  result = cuddSifting(table,lower,upper);
8722  if (initialSize <= table->keys - table->isolated)
8723  break;
8724 #ifdef DD_STATS
8725  else
8726  (void) fprintf(table->out,"\n");
8727 #endif
8728  } while (result != 0);
8729  break;
8731  result = cuddSymmSifting(table,lower,upper);
8732  break;
8734  result = cuddSymmSiftingConv(table,lower,upper);
8735  break;
8737  if (table->groupcheck == CUDD_NO_CHECK) {
8738  result = ddGroupSifting(table,lower,upper,ddNoCheck,
8739  DD_NORMAL_SIFT);
8740  } else if (table->groupcheck == CUDD_GROUP_CHECK5) {
8741  result = ddGroupSifting(table,lower,upper,ddExtSymmCheck,
8742  DD_NORMAL_SIFT);
8743  } else if (table->groupcheck == CUDD_GROUP_CHECK7) {
8744  result = ddGroupSifting(table,lower,upper,ddExtSymmCheck,
8745  DD_NORMAL_SIFT);
8746  } else {
8747  (void) fprintf(table->err,
8748  "Unknown group ckecking method\n");
8749  result = 0;
8750  }
8751  break;
8753  do {
8754  initialSize = table->keys - table->isolated;
8755  if (table->groupcheck == CUDD_NO_CHECK) {
8756  result = ddGroupSifting(table,lower,upper,ddNoCheck,
8757  DD_NORMAL_SIFT);
8758  } else if (table->groupcheck == CUDD_GROUP_CHECK5) {
8759  result = ddGroupSifting(table,lower,upper,ddExtSymmCheck,
8760  DD_NORMAL_SIFT);
8761  } else if (table->groupcheck == CUDD_GROUP_CHECK7) {
8762  result = ddGroupSifting(table,lower,upper,ddExtSymmCheck,
8763  DD_NORMAL_SIFT);
8764  } else {
8765  (void) fprintf(table->err,
8766  "Unknown group ckecking method\n");
8767  result = 0;
8768  }
8769 #ifdef DD_STATS
8770  (void) fprintf(table->out,"\n");
8771 #endif
8772  result = cuddWindowReorder(table,lower,upper,
8774  if (initialSize <= table->keys - table->isolated)
8775  break;
8776 #ifdef DD_STATS
8777  else
8778  (void) fprintf(table->out,"\n");
8779 #endif
8780  } while (result != 0);
8781  break;
8782  case CUDD_REORDER_WINDOW2:
8783  case CUDD_REORDER_WINDOW3:
8784  case CUDD_REORDER_WINDOW4:
8788  result = cuddWindowReorder(table,lower,upper,method);
8789  break;
8791  result = cuddAnnealing(table,lower,upper);
8792  break;
8793  case CUDD_REORDER_GENETIC:
8794  result = cuddGa(table,lower,upper);
8795  break;
8796  case CUDD_REORDER_LINEAR:
8797  result = cuddLinearAndSifting(table,lower,upper);
8798  break;
8800  do {
8801  initialSize = table->keys - table->isolated;
8802  result = cuddLinearAndSifting(table,lower,upper);
8803  if (initialSize <= table->keys - table->isolated)
8804  break;
8805 #ifdef DD_STATS
8806  else
8807  (void) fprintf(table->out,"\n");
8808 #endif
8809  } while (result != 0);
8810  break;
8811  case CUDD_REORDER_EXACT:
8812  result = cuddExact(table,lower,upper);
8813  break;
8815  result = ddGroupSifting(table,lower,upper,ddVarGroupCheck,
8816  DD_LAZY_SIFT);
8817  break;
8818  default:
8819  return(0);
8820  }
8821  }
8822 
8823  /* Create a single group for all the variables that were sifted,
8824  ** so that they will be treated as a single block by successive
8825  ** invocations of ddGroupSifting.
8826  */
8827  ddMergeGroups(table,treenode,lower,upper);
8828 
8829 #ifdef DD_DEBUG
8830  if (pr > 0) (void) fprintf(table->out,"ddReorderChildren:");
8831 #endif
8832 
8833  return(result);
8834 
8835 } /* end of ddReorderChildren */
Cudd_AggregationType groupcheck
Definition: cuddInt.h:410
MtrHalfWord flags
Definition: mtr.h:127
static int ddGroupSifting(DdManager *table, int lower, int upper, DD_CHKFP checkFunction, int lazyFlag)
Definition: cuddInt.c:8956
static void ddMergeGroups(DdManager *table, MtrNode *treenode, int low, int high)
Definition: cuddInt.c:10016
FILE * err
Definition: cuddInt.h:424
int cuddSymmSiftingConv(DdManager *table, int lower, int upper)
Definition: cuddInt.c:18163
int cuddAnnealing(DdManager *table, int lower, int upper)
Definition: cuddInt.c:761
#define MTR_FIXED
Definition: mtr.h:97
int cuddSifting(DdManager *table, int lower, int upper)
Definition: cuddInt.c:14824
static int ddVarGroupCheck(DdManager *table, int x, int y)
Definition: cuddInt.c:10329
int cuddExact(DdManager *table, int lower, int upper)
Definition: cuddInt.c:6474
int cuddGa(DdManager *table, int lower, int upper)
Definition: cuddInt.c:7533
static void ddFindNodeHiLo(DdManager *table, MtrNode *treenode, int *lower, int *upper)
Definition: cuddInt.c:8853
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
#define DD_NORMAL_SIFT
Definition: cuddInt.c:8391
int cuddSwapping(DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)
Definition: cuddInt.c:14926
#define DD_LAZY_SIFT
Definition: cuddInt.c:8392
int cuddLinearAndSifting(DdManager *table, int lower, int upper)
Definition: cuddInt.c:12750
static int ddExtSymmCheck(DdManager *table, int x, int y)
Definition: cuddInt.c:10179
static int result
Definition: cuddInt.c:7466
static int ddNoCheck(DdManager *table, int x, int y)
Definition: cuddInt.c:10098
int cuddWindowReorder(DdManager *table, int low, int high, Cudd_ReorderingType submethod)
Definition: cuddInt.c:24123
int isolated
Definition: cuddInt.h:368
int cuddSymmSifting(DdManager *table, int lower, int upper)
Definition: cuddInt.c:18042

◆ ddReorderPostprocess()

static int ddReorderPostprocess ( DdManager table)
static

Function********************************************************************

Synopsis [Cleans up at the end of reordering.]

Description []

SideEffects [None]

Definition at line 16185 of file cuddInt.c.

16187 {
16188 
16189 #ifdef DD_VERBOSE
16190  (void) fflush(table->out);
16191 #endif
16192 
16193  /* Free interaction matrix. */
16194  FREE(table->interact);
16195 
16196  return(1);
16197 
16198 } /* end of ddReorderPostprocess */
#define FREE(obj)
Definition: util.h:80
FILE * out
Definition: cuddInt.h:423
long * interact
Definition: cuddInt.h:377

◆ ddReorderPreprocess()

static int ddReorderPreprocess ( DdManager table)
static

Function********************************************************************

Synopsis [Prepares the DD heap for dynamic reordering.]

Description [Prepares the DD heap for dynamic reordering. Does garbage collection, to guarantee that there are no dead nodes; clears the cache, which is invalidated by dynamic reordering; initializes the number of isolated projection functions; and initializes the interaction matrix. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 16147 of file cuddInt.c.

16149 {
16150  int i;
16151  int res;
16152 
16153  /* Clear the cache. */
16154  cuddCacheFlush(table);
16155  cuddLocalCacheClearAll(table);
16156 
16157  /* Eliminate dead nodes. Do not scan the cache again. */
16158  cuddGarbageCollect(table,0);
16159 
16160  /* Initialize number of isolated projection functions. */
16161  table->isolated = 0;
16162  for (i = 0; i < table->size; i++) {
16163  if (table->vars[i]->ref == 1) table->isolated++;
16164  }
16165 
16166  /* Initialize the interaction matrix. */
16167  res = cuddInitInteract(table);
16168  if (res == 0) return(0);
16169 
16170  return(1);
16171 
16172 } /* end of ddReorderPreprocess */
DdHalfWord ref
Definition: cudd.h:266
int cuddInitInteract(DdManager *table)
Definition: cuddInt.c:10963
int size
Definition: cuddInt.h:345
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddInt.c:20120
void cuddLocalCacheClearAll(DdManager *manager)
Definition: cuddInt.c:11414
DdNode ** vars
Definition: cuddInt.h:373
void cuddCacheFlush(DdManager *table)
Definition: cuddInt.c:5070
int isolated
Definition: cuddInt.h:368

◆ ddReportRefMess()

static void ddReportRefMess ( DdManager unique,
int  i,
const char *  caller 
)
static

Function********************************************************************

Synopsis [Reports problem in garbage collection.]

Description []

SideEffects [None]

SeeAlso [cuddGarbageCollect cuddGarbageCollectZdd]

Definition at line 21976 of file cuddInt.c.

21980 {
21981 if (i == CUDD_CONST_INDEX) {
21982 (void) fprintf(unique->err,
21983 "%s: problem in constants\n", caller);
21984 } else if (i != -1) {
21985 (void) fprintf(unique->err,
21986 "%s: problem in table %d\n", caller, i);
21987 }
21988 (void) fprintf(unique->err, " dead count != deleted\n");
21989 (void) fprintf(unique->err, " This problem is often due to a missing \
21990 call to Cudd_Ref\n or to an extra call to Cudd_RecursiveDeref.\n \
21991 See the CUDD Programmer's Guide for additional details.");
21992 abort();
21993 
21994 } /* end of ddReportRefMess */
FILE * err
Definition: cuddInt.h:424
#define CUDD_CONST_INDEX
Definition: cudd.h:107
VOID_OR_INT abort()

◆ ddResetVarHandled()

static int ddResetVarHandled ( DdManager dd,
int  index 
)
static

Function********************************************************************

Synopsis [Resets a variable to be processed.]

Description [Resets a variable to be processed. This function is used for lazy sifting.]

SideEffects [none]

SeeAlso []

Definition at line 10393 of file cuddInt.c.

10396 {
10397  if (index >= dd->size || index < 0) return(0);
10398  dd->subtables[dd->perm[index]].varHandled = 0;
10399  return(1);
10400 
10401 } /* end of ddResetVarHandled */
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
int varHandled
Definition: cuddInt.h:322
int * perm
Definition: cuddInt.h:369

◆ ddResizeTable()

static int ddResizeTable ( DdManager unique,
int  index,
int  amount 
)
static

Function********************************************************************

Synopsis [Increases the number of subtables in a unique table so that it meets or exceeds index.]

Description [Increases the number of subtables in a unique table so that it meets or exceeds index. The parameter amount determines how much spare space is allocated to prevent too frequent resizing. If index is negative, the table is resized, but no new variables are created. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso [Cudd_Reserve cuddResizeTableZdd]

Definition at line 21378 of file cuddInt.c.

21382 {
21383 DdSubtable *newsubtables;
21384 DdNodePtr *newnodelist;
21385 DdNodePtr *newvars;
21386 DdNode *sentinel = &(unique->sentinel);
21387 int oldsize,newsize;
21388 int i,j,reorderSave;
21389 int numSlots = unique->initSlots;
21390 int *newperm, *newinvperm, *newmap;
21391 DdNode *one, *zero;
21392 
21393 oldsize = unique->size;
21394 /* Easy case: there is still room in the current table. */
21395 if (index >= 0 && index < unique->maxSize) {
21396 for (i = oldsize; i <= index; i++) {
21397 unique->subtables[i].slots = numSlots;
21398 unique->subtables[i].shift = sizeof(int) * 8 -
21399 cuddComputeFloorLog2(numSlots);
21400 unique->subtables[i].keys = 0;
21401 unique->subtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY;
21402 unique->subtables[i].dead = 0;
21403 unique->subtables[i].bindVar = 0;
21405 unique->subtables[i].pairIndex = 0;
21406 unique->subtables[i].varHandled = 0;
21408 
21409 unique->perm[i] = i;
21410 unique->invperm[i] = i;
21411 newnodelist = unique->subtables[i].nodelist =
21412 ALLOC(DdNodePtr, numSlots);
21413 if (newnodelist == NULL) {
21414 for (j = oldsize; j < i; j++) {
21415 FREE(unique->subtables[j].nodelist);
21416 }
21417 unique->errorCode = CUDD_MEMORY_OUT;
21418 return(0);
21419 }
21420 for (j = 0; j < numSlots; j++) {
21421 newnodelist[j] = sentinel;
21422 }
21423 }
21424 if (unique->map != NULL) {
21425 for (i = oldsize; i <= index; i++) {
21426 unique->map[i] = i;
21427 }
21428 }
21429 } else {
21430 /* The current table is too small: we need to allocate a new,
21431 ** larger one; move all old subtables, and initialize the new
21432 ** subtables up to index included.
21433 */
21434 newsize = (index < 0) ? amount : index + amount;
21435 #ifdef DD_VERBOSE
21436 (void) fprintf(unique->err,
21437 "Increasing the table size from %d to %d\n",
21438 unique->maxSize, newsize);
21439 #endif
21440 newsubtables = ALLOC(DdSubtable,newsize);
21441 if (newsubtables == NULL) {
21442 unique->errorCode = CUDD_MEMORY_OUT;
21443 return(0);
21444 }
21445 newvars = ALLOC(DdNodePtr,newsize);
21446 if (newvars == NULL) {
21447 FREE(newsubtables);
21448 unique->errorCode = CUDD_MEMORY_OUT;
21449 return(0);
21450 }
21451 newperm = ALLOC(int,newsize);
21452 if (newperm == NULL) {
21453 FREE(newsubtables);
21454 FREE(newvars);
21455 unique->errorCode = CUDD_MEMORY_OUT;
21456 return(0);
21457 }
21458 newinvperm = ALLOC(int,newsize);
21459 if (newinvperm == NULL) {
21460 FREE(newsubtables);
21461 FREE(newvars);
21462 FREE(newperm);
21463 unique->errorCode = CUDD_MEMORY_OUT;
21464 return(0);
21465 }
21466 if (unique->map != NULL) {
21467 newmap = ALLOC(int,newsize);
21468 if (newmap == NULL) {
21469 FREE(newsubtables);
21470 FREE(newvars);
21471 FREE(newperm);
21472 FREE(newinvperm);
21473 unique->errorCode = CUDD_MEMORY_OUT;
21474 return(0);
21475 }
21476 unique->memused += (newsize - unique->maxSize) * sizeof(int);
21477 }
21478 unique->memused += (newsize - unique->maxSize) * ((numSlots+1) *
21479 sizeof(DdNode *) + 2 * sizeof(int) + sizeof(DdSubtable));
21480 if (newsize > unique->maxSizeZ) {
21481 FREE(unique->stack);
21482 unique->stack = ALLOC(DdNodePtr,newsize + 1);
21483 if (unique->stack == NULL) {
21484 FREE(newsubtables);
21485 FREE(newvars);
21486 FREE(newperm);
21487 FREE(newinvperm);
21488 if (unique->map != NULL) {
21489 FREE(newmap);
21490 }
21491 unique->errorCode = CUDD_MEMORY_OUT;
21492 return(0);
21493 }
21494 unique->stack[0] = NULL; /* to suppress harmless UMR */
21495 unique->memused +=
21496 (newsize - ddMax(unique->maxSize,unique->maxSizeZ))
21497 * sizeof(DdNode *);
21498 }
21499 for (i = 0; i < oldsize; i++) {
21500 newsubtables[i].slots = unique->subtables[i].slots;
21501 newsubtables[i].shift = unique->subtables[i].shift;
21502 newsubtables[i].keys = unique->subtables[i].keys;
21503 newsubtables[i].maxKeys = unique->subtables[i].maxKeys;
21504 newsubtables[i].dead = unique->subtables[i].dead;
21505 newsubtables[i].nodelist = unique->subtables[i].nodelist;
21506 newsubtables[i].bindVar = unique->subtables[i].bindVar;
21507 newsubtables[i].varType = unique->subtables[i].varType;
21508 newsubtables[i].pairIndex = unique->subtables[i].pairIndex;
21509 newsubtables[i].varHandled = unique->subtables[i].varHandled;
21510 newsubtables[i].varToBeGrouped = unique->subtables[i].varToBeGrouped;
21511 
21512 newvars[i] = unique->vars[i];
21513 newperm[i] = unique->perm[i];
21514 newinvperm[i] = unique->invperm[i];
21515 }
21516 for (i = oldsize; i <= index; i++) {
21517 newsubtables[i].slots = numSlots;
21518 newsubtables[i].shift = sizeof(int) * 8 -
21519 cuddComputeFloorLog2(numSlots);
21520 newsubtables[i].keys = 0;
21521 newsubtables[i].maxKeys = numSlots * DD_MAX_SUBTABLE_DENSITY;
21522 newsubtables[i].dead = 0;
21523 newsubtables[i].bindVar = 0;
21524 newsubtables[i].varType = CUDD_VAR_PRIMARY_INPUT;
21525 newsubtables[i].pairIndex = 0;
21526 newsubtables[i].varHandled = 0;
21527 newsubtables[i].varToBeGrouped = CUDD_LAZY_NONE;
21528 
21529 newperm[i] = i;
21530 newinvperm[i] = i;
21531 newnodelist = newsubtables[i].nodelist = ALLOC(DdNodePtr, numSlots);
21532 if (newnodelist == NULL) {
21533 unique->errorCode = CUDD_MEMORY_OUT;
21534 return(0);
21535 }
21536 for (j = 0; j < numSlots; j++) {
21537 newnodelist[j] = sentinel;
21538 }
21539 }
21540 if (unique->map != NULL) {
21541 for (i = 0; i < oldsize; i++) {
21542 newmap[i] = unique->map[i];
21543 }
21544 for (i = oldsize; i <= index; i++) {
21545 newmap[i] = i;
21546 }
21547 FREE(unique->map);
21548 unique->map = newmap;
21549 }
21550 FREE(unique->subtables);
21551 unique->subtables = newsubtables;
21552 unique->maxSize = newsize;
21553 FREE(unique->vars);
21554 unique->vars = newvars;
21555 FREE(unique->perm);
21556 unique->perm = newperm;
21557 FREE(unique->invperm);
21558 unique->invperm = newinvperm;
21559 }
21560 
21561 /* Now that the table is in a coherent state, create the new
21562 ** projection functions. We need to temporarily disable reordering,
21563 ** because we cannot reorder without projection functions in place.
21564 **/
21565 if (index >= 0) {
21566 one = unique->one;
21567 zero = Cudd_Not(one);
21568 
21569 unique->size = index + 1;
21570 if (unique->tree != NULL) {
21571 unique->tree->size = ddMax(unique->tree->size, unique->size);
21572 }
21573 unique->slots += (index + 1 - oldsize) * numSlots;
21574 ddFixLimits(unique);
21575 
21576 reorderSave = unique->autoDyn;
21577 unique->autoDyn = 0;
21578 for (i = oldsize; i <= index; i++) {
21579 unique->vars[i] = cuddUniqueInter(unique,i,one,zero);
21580 if (unique->vars[i] == NULL) {
21581 unique->autoDyn = reorderSave;
21582 for (j = oldsize; j < i; j++) {
21583 Cudd_IterDerefBdd(unique,unique->vars[j]);
21584 cuddDeallocNode(unique,unique->vars[j]);
21585 unique->vars[j] = NULL;
21586 }
21587 for (j = oldsize; j <= index; j++) {
21588 FREE(unique->subtables[j].nodelist);
21589 unique->subtables[j].nodelist = NULL;
21590 }
21591 unique->size = oldsize;
21592 unique->slots -= (index + 1 - oldsize) * numSlots;
21593 ddFixLimits(unique);
21594 return(0);
21595 }
21596 cuddRef(unique->vars[i]);
21597 }
21598 unique->autoDyn = reorderSave;
21599 }
21600 
21601 return(1);
21602 
21603 } /* end of ddResizeTable */
#define cuddRef(n)
Definition: cuddInt.h:557
unsigned int keys
Definition: cuddInt.h:314
DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E)
Definition: cuddInt.c:20495
int maxSizeZ
Definition: cuddInt.h:348
int * map
Definition: cuddInt.h:374
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
MtrHalfWord size
Definition: mtr.h:129
#define FREE(obj)
Definition: util.h:80
static DD_INLINE void ddFixLimits(DdManager *unique)
Definition: cuddInt.c:21624
int size
Definition: cuddInt.h:345
static DdNode * one
Definition: cuddInt.c:16562
unsigned int slots
Definition: cuddInt.h:352
FILE * err
Definition: cuddInt.h:424
int bindVar
Definition: cuddInt.h:318
DdSubtable * subtables
Definition: cuddInt.h:349
MtrNode * tree
Definition: cuddInt.h:408
struct DdSubtable DdSubtable
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
DdNode ** stack
Definition: cuddInt.h:364
unsigned int initSlots
Definition: cuddInt.h:363
Cudd_VariableType varType
Definition: cuddInt.h:320
DdNode sentinel
Definition: cuddInt.h:328
#define ALLOC(type, num)
Definition: util.h:76
unsigned int dead
Definition: cuddInt.h:316
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14090
Cudd_LazyGroupType varToBeGrouped
Definition: cuddInt.h:323
int maxSize
Definition: cuddInt.h:347
unsigned int maxKeys
Definition: cuddInt.h:315
#define ddMax(x, y)
Definition: cuddInt.h:785
DdNode ** nodelist
Definition: cuddInt.h:311
int varHandled
Definition: cuddInt.h:322
#define cuddDeallocNode(unique, node)
Definition: cuddInt.h:520
unsigned long memused
Definition: cuddInt.h:429
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddInt.c:5102
unsigned int slots
Definition: cuddInt.h:313
DdNode ** vars
Definition: cuddInt.h:373
int pairIndex
Definition: cuddInt.h:321
DdNode * one
Definition: cuddInt.h:329
int * invperm
Definition: cuddInt.h:371
static DdNode * zero
Definition: cuddInt.c:16562
int autoDyn
Definition: cuddInt.h:400
int shift
Definition: cuddInt.h:312
int * perm
Definition: cuddInt.h:369
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ ddSecDiffCheck()

static int ddSecDiffCheck ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [Checks two variables for aggregation.]

Description [Checks two variables for aggregation. The check is based on the second difference of the number of nodes as a function of the layer. If the second difference is lower than a given threshold (typically negative) then the two variables should be aggregated. Returns 1 if the two variables pass the test; 0 otherwise.]

SideEffects [None]

Definition at line 10122 of file cuddInt.c.

10126 {
10127  double Nx,Nx_1;
10128  double Sx;
10129  double threshold;
10130  int xindex,yindex;
10131 
10132  if (x==0) return(0);
10133 
10134 #ifdef DD_STATS
10135  secdiffcalls++;
10136 #endif
10137  Nx = (double) table->subtables[x].keys;
10138  Nx_1 = (double) table->subtables[x-1].keys;
10139  Sx = (table->subtables[y].keys/Nx) - (Nx/Nx_1);
10140 
10141  threshold = table->recomb / 100.0;
10142  if (Sx < threshold) {
10143  xindex = table->invperm[x];
10144  yindex = table->invperm[y];
10145  if (cuddTestInteract(table,xindex,yindex)) {
10146 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
10147  (void) fprintf(table->out,
10148  "Second difference for %d = %g Pos(%d)\n",
10149  table->invperm[x],Sx,x);
10150 #endif
10151 #ifdef DD_STATS
10152  secdiff++;
10153 #endif
10154  return(1);
10155  } else {
10156 #ifdef DD_STATS
10157  secdiffmisfire++;
10158 #endif
10159  return(0);
10160  }
10161 
10162  }
10163  return(0);
10164 
10165 } /* end of ddSecDiffCheck */
unsigned int keys
Definition: cuddInt.h:314
DdSubtable * subtables
Definition: cuddInt.h:349
int recomb
Definition: cuddInt.h:411
FILE * out
Definition: cuddInt.h:423
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917
int * invperm
Definition: cuddInt.h:371

◆ ddSetVarHandled()

static int ddSetVarHandled ( DdManager dd,
int  index 
)
static

Function********************************************************************

Synopsis [Sets a variable to already handled.]

Description [Sets a variable to already handled. This function is used for lazy sifting.]

SideEffects [none]

SeeAlso []

Definition at line 10369 of file cuddInt.c.

10372 {
10373  if (index >= dd->size || index < 0) return(0);
10374  dd->subtables[dd->perm[index]].varHandled = 1;
10375  return(1);
10376 
10377 } /* end of ddSetVarHandled */
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
int varHandled
Definition: cuddInt.h:322
int * perm
Definition: cuddInt.h:369

◆ ddShuffle()

static int ddShuffle ( DdManager table,
DdHalfWord permutation,
int  lower,
int  upper 
)
static

Function********************************************************************

Synopsis [Reorders variables according to a given permutation.]

Description [Reorders variables according to a given permutation. The i-th permutation array contains the index of the variable that should be brought to the i-th level. ddShuffle assumes that no dead nodes are present and that the interaction matrix is properly initialized. The reordering is achieved by a series of upward sifts. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 6862 of file cuddInt.c.

6867 {
6868  DdHalfWord index;
6869  int level;
6870  int position;
6871 #if 0
6872  int numvars;
6873 #endif
6874  int result;
6875 #ifdef DD_STATS
6876  unsigned long localTime;
6877  int initialSize;
6878 #ifdef DD_VERBOSE
6879  int finalSize;
6880 #endif
6881  int previousSize;
6882 #endif
6883 
6884 #ifdef DD_STATS
6885  localTime = util_cpu_time();
6886  initialSize = table->keys - table->isolated;
6887 #endif
6888 
6889 #if 0
6890  numvars = table->size;
6891 
6892  (void) fprintf(table->out,"%d:", ddTotalShuffles);
6893  for (level = 0; level < numvars; level++) {
6894  (void) fprintf(table->out," %d", table->invperm[level]);
6895  }
6896  (void) fprintf(table->out,"\n");
6897 #endif
6898 
6899  for (level = 0; level <= upper - lower; level++) {
6900  index = permutation[level];
6901  position = table->perm[index];
6902 #ifdef DD_STATS
6903  previousSize = table->keys - table->isolated;
6904 #endif
6905  result = ddSiftUp(table,position,level+lower);
6906  if (!result) return(0);
6907  }
6908 
6909 #ifdef DD_STATS
6910  ddTotalShuffles++;
6911 #ifdef DD_VERBOSE
6912  finalSize = table->keys - table->isolated;
6913  if (finalSize < initialSize) {
6914  (void) fprintf(table->out,"-");
6915  } else if (finalSize > initialSize) {
6916  (void) fprintf(table->out,"+");
6917  } else {
6918  (void) fprintf(table->out,"=");
6919  }
6920  if ((ddTotalShuffles & 63) == 0) (void) fprintf(table->out,"\n");
6921  fflush(table->out);
6922 #endif
6923 #endif
6924 
6925  return(1);
6926 
6927 } /* end of ddShuffle */
unsigned short DdHalfWord
Definition: cudd.h:253
int size
Definition: cuddInt.h:345
static int numvars
Definition: cuddInt.c:7452
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
long util_cpu_time(void)
Definition: util.c:34
static int result
Definition: cuddInt.c:7466
static int ddSiftUp(DdManager *table, int x, int xLow)
Definition: cuddInt.c:6944
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int * perm
Definition: cuddInt.h:369

◆ ddShuffle2()

static int ddShuffle2 ( DdManager table,
int *  permutation 
)
static

Function********************************************************************

Synopsis [Reorders variables according to a given permutation.]

Description [Reorders variables according to a given permutation. The i-th permutation array contains the index of the variable that should be brought to the i-th level. ddShuffle assumes that no dead nodes are present and that the interaction matrix is properly initialized. The reordering is achieved by a series of upward sifts. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 16218 of file cuddInt.c.

16221 {
16222  int index;
16223  int level;
16224  int position;
16225  int numvars;
16226  int result;
16227 #ifdef DD_STATS
16228  unsigned long localTime;
16229  int initialSize;
16230  int finalSize;
16231  int previousSize;
16232 #endif
16233 
16235 #ifdef DD_STATS
16236  localTime = util_cpu_time();
16237  initialSize = table->keys - table->isolated;
16238  (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n",
16239  initialSize);
16240  ddTotalNISwaps = 0;
16241 #endif
16242 
16243  numvars = table->size;
16244 
16245  for (level = 0; level < numvars; level++) {
16246  index = permutation[level];
16247  position = table->perm[index];
16248 #ifdef DD_STATS
16249  previousSize = table->keys - table->isolated;
16250 #endif
16251  result = ddSiftUp2(table,position,level);
16252  if (!result) return(0);
16253 #ifdef DD_STATS
16254  if (table->keys < (unsigned) previousSize + table->isolated) {
16255  (void) fprintf(table->out,"-");
16256  } else if (table->keys > (unsigned) previousSize + table->isolated) {
16257  (void) fprintf(table->out,"+"); /* should never happen */
16258  } else {
16259  (void) fprintf(table->out,"=");
16260  }
16261  fflush(table->out);
16262 #endif
16263  }
16264 
16265 #ifdef DD_STATS
16266  (void) fprintf(table->out,"\n");
16267  finalSize = table->keys - table->isolated;
16268  (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize);
16269  (void) fprintf(table->out,"#:T_SHUFFLE %8g: total time (sec)\n",
16270  ((double)(util_cpu_time() - localTime)/1000.0));
16271  (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n",
16273  (void) fprintf(table->out,"#:M_SHUFFLE %8d: NI swaps\n",ddTotalNISwaps);
16274 #endif
16275 
16276  return(1);
16277 
16278 } /* end of ddShuffle */
static int ddSiftUp2(DdManager *table, int x, int xLow)
Definition: cuddInt.c:16295
int size
Definition: cuddInt.h:345
static int numvars
Definition: cuddInt.c:7452
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
long util_cpu_time(void)
Definition: util.c:34
static int result
Definition: cuddInt.c:7466
int isolated
Definition: cuddInt.h:368
int ddTotalNumberSwapping
Definition: cuddInt.c:14489
int * perm
Definition: cuddInt.h:369

◆ ddSiftingAux()

static int ddSiftingAux ( DdManager table,
int  x,
int  xLow,
int  xHigh 
)
static

Function********************************************************************

Synopsis [Given xLow <= x <= xHigh moves x up and down between the boundaries.]

Description [Given xLow <= x <= xHigh moves x up and down between the boundaries. Finds the best position and does the required changes. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 15809 of file cuddInt.c.

15814 {
15815 
15816  Move *move;
15817  Move *moveUp; /* list of up moves */
15818  Move *moveDown; /* list of down moves */
15819  int initialSize;
15820  int result;
15821 
15822  initialSize = table->keys - table->isolated;
15823 
15824  moveDown = NULL;
15825  moveUp = NULL;
15826 
15827  if (x == xLow) {
15828  moveDown = ddSiftingDown(table,x,xHigh);
15829  /* At this point x --> xHigh unless bounding occurred. */
15830  if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem;
15831  /* Move backward and stop at best position. */
15832  result = ddSiftingBackward(table,initialSize,moveDown);
15833  if (!result) goto ddSiftingAuxOutOfMem;
15834 
15835  } else if (x == xHigh) {
15836  moveUp = ddSiftingUp(table,x,xLow);
15837  /* At this point x --> xLow unless bounding occurred. */
15838  if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem;
15839  /* Move backward and stop at best position. */
15840  result = ddSiftingBackward(table,initialSize,moveUp);
15841  if (!result) goto ddSiftingAuxOutOfMem;
15842 
15843  } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */
15844  moveDown = ddSiftingDown(table,x,xHigh);
15845  /* At this point x --> xHigh unless bounding occurred. */
15846  if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem;
15847  if (moveDown != NULL) {
15848  x = moveDown->y;
15849  }
15850  moveUp = ddSiftingUp(table,x,xLow);
15851  if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem;
15852  /* Move backward and stop at best position */
15853  result = ddSiftingBackward(table,initialSize,moveUp);
15854  if (!result) goto ddSiftingAuxOutOfMem;
15855 
15856  } else { /* must go up first: shorter */
15857  moveUp = ddSiftingUp(table,x,xLow);
15858  /* At this point x --> xLow unless bounding occurred. */
15859  if (moveUp == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem;
15860  if (moveUp != NULL) {
15861  x = moveUp->x;
15862  }
15863  moveDown = ddSiftingDown(table,x,xHigh);
15864  if (moveDown == (Move *) CUDD_OUT_OF_MEM) goto ddSiftingAuxOutOfMem;
15865  /* Move backward and stop at best position. */
15866  result = ddSiftingBackward(table,initialSize,moveDown);
15867  if (!result) goto ddSiftingAuxOutOfMem;
15868  }
15869 
15870  while (moveDown != NULL) {
15871  move = moveDown->next;
15872  cuddDeallocMove(table, moveDown);
15873  moveDown = move;
15874  }
15875  while (moveUp != NULL) {
15876  move = moveUp->next;
15877  cuddDeallocMove(table, moveUp);
15878  moveUp = move;
15879  }
15880 
15881  return(1);
15882 
15883  ddSiftingAuxOutOfMem:
15884  if (moveDown != (Move *) CUDD_OUT_OF_MEM) {
15885  while (moveDown != NULL) {
15886  move = moveDown->next;
15887  cuddDeallocMove(table, moveDown);
15888  moveDown = move;
15889  }
15890  }
15891  if (moveUp != (Move *) CUDD_OUT_OF_MEM) {
15892  while (moveUp != NULL) {
15893  move = moveUp->next;
15894  cuddDeallocMove(table, moveUp);
15895  moveUp = move;
15896  }
15897  }
15898 
15899  return(0);
15900 
15901 } /* end of ddSiftingAux */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
static Move * ddSiftingDown(DdManager *table, int x, int xHigh)
Definition: cuddInt.c:16016
Definition: cuddInt.h:469
static int ddSiftingBackward(DdManager *table, int size, Move *moves)
Definition: cuddInt.c:16108
static Move * ddSiftingUp(DdManager *table, int y, int xLow)
Definition: cuddInt.c:15916
unsigned int keys
Definition: cuddInt.h:353
DdHalfWord x
Definition: cuddInt.h:470
static int result
Definition: cuddInt.c:7466
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int isolated
Definition: cuddInt.h:368

◆ ddSiftingBackward()

static int ddSiftingBackward ( DdManager table,
int  size,
Move moves 
)
static

Function********************************************************************

Synopsis [Given a set of moves, returns the DD heap to the position giving the minimum size.]

Description [Given a set of moves, returns the DD heap to the position giving the minimum size. In case of ties, returns to the closest position giving the minimum size. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 16108 of file cuddInt.c.

16112 {
16113  Move *move;
16114  int res;
16115 
16116  for (move = moves; move != NULL; move = move->next) {
16117  if (move->size < size) {
16118  size = move->size;
16119  }
16120  }
16121 
16122  for (move = moves; move != NULL; move = move->next) {
16123  if (move->size == size) return(1);
16124  res = cuddSwapInPlace(table,(int)move->x,(int)move->y);
16125  if (!res) return(0);
16126  }
16127 
16128  return(1);
16129 
16130 } /* end of ddSiftingBackward */
Definition: cuddInt.h:469
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
DdHalfWord x
Definition: cuddInt.h:470
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473

◆ ddSiftingDown()

static Move * ddSiftingDown ( DdManager table,
int  x,
int  xHigh 
)
static

Function********************************************************************

Synopsis [Sifts a variable down.]

Description [Sifts a variable down. Moves x down until either it reaches the bound (xHigh) or the size of the DD heap increases too much. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

Definition at line 16016 of file cuddInt.c.

16020 {
16021  Move *moves;
16022  Move *move;
16023  int y;
16024  int size;
16025  int R; /* upper bound on node decrease */
16026  int limitSize;
16027  int xindex, yindex;
16028  int isolated;
16029 #ifdef DD_DEBUG
16030  int checkR;
16031  int z;
16032  int zindex;
16033 #endif
16034 
16035  moves = NULL;
16036  /* Initialize R */
16037  xindex = table->invperm[x];
16038  limitSize = size = table->keys - table->isolated;
16039  R = 0;
16040  for (y = xHigh; y > x; y--) {
16041  yindex = table->invperm[y];
16042  if (cuddTestInteract(table,xindex,yindex)) {
16043  isolated = table->vars[yindex]->ref == 1;
16044  R += table->subtables[y].keys - isolated;
16045  }
16046  }
16047 
16048  y = cuddNextHigh(table,x);
16049  while (y <= xHigh && size - R < limitSize) {
16050 #ifdef DD_DEBUG
16051  checkR = 0;
16052  for (z = xHigh; z > x; z--) {
16053  zindex = table->invperm[z];
16054  if (cuddTestInteract(table,xindex,zindex)) {
16055  isolated = table->vars[zindex]->ref == 1;
16056  checkR += table->subtables[z].keys - isolated;
16057  }
16058  }
16059  assert(R == checkR);
16060 #endif
16061  /* Update upper bound on node decrease. */
16062  yindex = table->invperm[y];
16063  if (cuddTestInteract(table,xindex,yindex)) {
16064  isolated = table->vars[yindex]->ref == 1;
16065  R -= table->subtables[y].keys - isolated;
16066  }
16067  size = cuddSwapInPlace(table,x,y);
16068  if (size == 0) goto ddSiftingDownOutOfMem;
16069  move = (Move *) cuddDynamicAllocNode(table);
16070  if (move == NULL) goto ddSiftingDownOutOfMem;
16071  move->x = x;
16072  move->y = y;
16073  move->size = size;
16074  move->next = moves;
16075  moves = move;
16076  if ((double) size > (double) limitSize * table->maxGrowth) break;
16077  if (size < limitSize) limitSize = size;
16078  x = y;
16079  y = cuddNextHigh(table,x);
16080  }
16081  return(moves);
16082 
16083  ddSiftingDownOutOfMem:
16084  while (moves != NULL) {
16085  move = moves->next;
16086  cuddDeallocMove(table, moves);
16087  moves = move;
16088  }
16089  return((Move *) CUDD_OUT_OF_MEM);
16090 
16091 } /* end of ddSiftingDown */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
unsigned int keys
Definition: cuddInt.h:353
DdHalfWord x
Definition: cuddInt.h:470
DdHalfWord y
Definition: cuddInt.h:471
DdNode ** vars
Definition: cuddInt.h:373
struct Move * next
Definition: cuddInt.h:474
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int size
Definition: cuddInt.h:473

◆ ddSiftingUp()

static Move * ddSiftingUp ( DdManager table,
int  y,
int  xLow 
)
static

Function********************************************************************

Synopsis [Sifts a variable up.]

Description [Sifts a variable up. Moves y up until either it reaches the bound (xLow) or the size of the DD heap increases too much. Returns the set of moves in case of success; NULL if memory is full.]

SideEffects [None]

Definition at line 15916 of file cuddInt.c.

15920 {
15921  Move *moves;
15922  Move *move;
15923  int x;
15924  int size;
15925  int limitSize;
15926  int xindex, yindex;
15927  int isolated;
15928  int L; /* lower bound on DD size */
15929 #ifdef DD_DEBUG
15930  int checkL;
15931  int z;
15932  int zindex;
15933 #endif
15934 
15935  moves = NULL;
15936  yindex = table->invperm[y];
15937 
15938  /* Initialize the lower bound.
15939  ** The part of the DD below y will not change.
15940  ** The part of the DD above y that does not interact with y will not
15941  ** change. The rest may vanish in the best case, except for
15942  ** the nodes at level xLow, which will not vanish, regardless.
15943  */
15944  limitSize = L = table->keys - table->isolated;
15945  for (x = xLow + 1; x < y; x++) {
15946  xindex = table->invperm[x];
15947  if (cuddTestInteract(table,xindex,yindex)) {
15948  isolated = table->vars[xindex]->ref == 1;
15949  L -= table->subtables[x].keys - isolated;
15950  }
15951  }
15952  isolated = table->vars[yindex]->ref == 1;
15953  L -= table->subtables[y].keys - isolated;
15954 
15955  x = cuddNextLow(table,y);
15956  while (x >= xLow && L <= limitSize) {
15957  xindex = table->invperm[x];
15958 #ifdef DD_DEBUG
15959  checkL = table->keys - table->isolated;
15960  for (z = xLow + 1; z < y; z++) {
15961  zindex = table->invperm[z];
15962  if (cuddTestInteract(table,zindex,yindex)) {
15963  isolated = table->vars[zindex]->ref == 1;
15964  checkL -= table->subtables[z].keys - isolated;
15965  }
15966  }
15967  isolated = table->vars[yindex]->ref == 1;
15968  checkL -= table->subtables[y].keys - isolated;
15969  assert(L == checkL);
15970 #endif
15971  size = cuddSwapInPlace(table,x,y);
15972  if (size == 0) goto ddSiftingUpOutOfMem;
15973  /* Update the lower bound. */
15974  if (cuddTestInteract(table,xindex,yindex)) {
15975  isolated = table->vars[xindex]->ref == 1;
15976  L += table->subtables[y].keys - isolated;
15977  }
15978  move = (Move *) cuddDynamicAllocNode(table);
15979  if (move == NULL) goto ddSiftingUpOutOfMem;
15980  move->x = x;
15981  move->y = y;
15982  move->size = size;
15983  move->next = moves;
15984  moves = move;
15985  if ((double) size > (double) limitSize * table->maxGrowth) break;
15986  if (size < limitSize) limitSize = size;
15987  y = x;
15988  x = cuddNextLow(table,y);
15989  }
15990  return(moves);
15991 
15992  ddSiftingUpOutOfMem:
15993  while (moves != NULL) {
15994  move = moves->next;
15995  cuddDeallocMove(table, moves);
15996  moves = move;
15997  }
15998  return((Move *) CUDD_OUT_OF_MEM);
15999 
16000 } /* end of ddSiftingUp */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
unsigned int keys
Definition: cuddInt.h:353
DdHalfWord x
Definition: cuddInt.h:470
DdHalfWord y
Definition: cuddInt.h:471
DdNode ** vars
Definition: cuddInt.h:373
struct Move * next
Definition: cuddInt.h:474
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int size
Definition: cuddInt.h:473

◆ ddSiftUp()

static int ddSiftUp ( DdManager table,
int  x,
int  xLow 
)
static

Function********************************************************************

Synopsis [Moves one variable up.]

Description [Takes a variable from position x and sifts it up to position xLow; xLow should be less than or equal to x. Returns 1 if successful; 0 otherwise]

SideEffects [None]

SeeAlso []

Definition at line 6944 of file cuddInt.c.

6948 {
6949  int y;
6950  int size;
6951 
6952  y = cuddNextLow(table,x);
6953  while (y >= xLow) {
6954  size = cuddSwapInPlace(table,y,x);
6955  if (size == 0) {
6956  return(0);
6957  }
6958  x = y;
6959  y = cuddNextLow(table,x);
6960  }
6961  return(1);
6962 
6963 } /* end of ddSiftUp */
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082

◆ ddSiftUp2()

static int ddSiftUp2 ( DdManager table,
int  x,
int  xLow 
)
static

Function********************************************************************

Synopsis [Moves one variable up.]

Description [Takes a variable from position x and sifts it up to position xLow; xLow should be less than or equal to x. Returns 1 if successful; 0 otherwise]

SideEffects [None]

SeeAlso []

Definition at line 16295 of file cuddInt.c.

16299 {
16300  int y;
16301  int size;
16302 
16303  y = cuddNextLow(table,x);
16304  while (y >= xLow) {
16305  size = cuddSwapInPlace(table,y,x);
16306  if (size == 0) {
16307  return(0);
16308  }
16309  x = y;
16310  y = cuddNextLow(table,x);
16311  }
16312  return(1);
16313 
16314 } /* end of ddSiftUp */
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082

◆ ddSuppInteract()

static void ddSuppInteract ( DdNode f,
char *  support 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Find the support of f.]

Description [Performs a DFS from f. Uses the LSB of the then pointer as visited flag.]

SideEffects [Accumulates in support the variables on which f depends.]

SeeAlso []

Definition at line 11043 of file cuddInt.c.

11046 {
11047  if (cuddIsConstant(f) || Cudd_IsComplement(cuddT(f))) {
11048  return;
11049  }
11050 
11051  support[f->index] = 1;
11052  ddSuppInteract(cuddT(f),support);
11053  ddSuppInteract(Cudd_Regular(cuddE(f)),support);
11054  /* mark as visited */
11055  cuddT(f) = Cudd_Complement(cuddT(f));
11056  f->next = Cudd_Complement(f->next);
11057  return;
11058 
11059 } /* end of ddSuppInteract */
#define Cudd_Regular(node)
Definition: cudd.h:373
static void ddSuppInteract(DdNode *f, char *support)
Definition: cuddInt.c:11043
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode * next
Definition: cudd.h:267
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define Cudd_Complement(node)
Definition: cudd.h:387
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625

◆ ddSupportStep()

static void ddSupportStep ( DdNode f,
int *  support 
)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_Support.]

Description [Performs the recursive step of Cudd_Support. Performs a DFS from f. The support is accumulated in supp as a side effect. Uses the LSB of the then pointer as visited flag.]

SideEffects [None]

SeeAlso [ddClearFlag]

Definition at line 23792 of file cuddInt.c.

23795 {
23796 if (cuddIsConstant(f) || Cudd_IsComplement(f->next))
23797 return;
23798 
23799 support[f->index] = 1;
23800 ddSupportStep(cuddT(f),support);
23801 ddSupportStep(Cudd_Regular(cuddE(f)),support);
23802 /* Mark as visited. */
23803 f->next = Cudd_Complement(f->next);
23804 
23805 } /* end of ddSupportStep */
#define Cudd_Regular(node)
Definition: cudd.h:373
#define Cudd_IsComplement(node)
Definition: cudd.h:401
DdNode * next
Definition: cudd.h:267
#define cuddIsConstant(node)
Definition: cuddInt.h:593
static void ddSupportStep(DdNode *f, int *support)
Definition: cuddInt.c:23792
#define Cudd_Complement(node)
Definition: cudd.h:387
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625

◆ ddSwapAny()

static Move * ddSwapAny ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [Swaps any two variables.]

Description [Swaps any two variables. Returns the set of moves.]

SideEffects [None]

Definition at line 15668 of file cuddInt.c.

15672 {
15673  Move *move, *moves;
15674  int xRef,yRef;
15675  int xNext,yNext;
15676  int size;
15677  int limitSize;
15678  int tmp;
15679 
15680  if (x >y) {
15681  tmp = x; x = y; y = tmp;
15682  }
15683 
15684  xRef = x; yRef = y;
15685 
15686  xNext = cuddNextHigh(table,x);
15687  yNext = cuddNextLow(table,y);
15688  moves = NULL;
15689  limitSize = table->keys - table->isolated;
15690 
15691  for (;;) {
15692  if ( xNext == yNext) {
15693  size = cuddSwapInPlace(table,x,xNext);
15694  if (size == 0) goto ddSwapAnyOutOfMem;
15695  move = (Move *) cuddDynamicAllocNode(table);
15696  if (move == NULL) goto ddSwapAnyOutOfMem;
15697  move->x = x;
15698  move->y = xNext;
15699  move->size = size;
15700  move->next = moves;
15701  moves = move;
15702 
15703  size = cuddSwapInPlace(table,yNext,y);
15704  if (size == 0) goto ddSwapAnyOutOfMem;
15705  move = (Move *) cuddDynamicAllocNode(table);
15706  if (move == NULL) goto ddSwapAnyOutOfMem;
15707  move->x = yNext;
15708  move->y = y;
15709  move->size = size;
15710  move->next = moves;
15711  moves = move;
15712 
15713  size = cuddSwapInPlace(table,x,xNext);
15714  if (size == 0) goto ddSwapAnyOutOfMem;
15715  move = (Move *) cuddDynamicAllocNode(table);
15716  if (move == NULL) goto ddSwapAnyOutOfMem;
15717  move->x = x;
15718  move->y = xNext;
15719  move->size = size;
15720  move->next = moves;
15721  moves = move;
15722 
15723  tmp = x; x = y; y = tmp;
15724 
15725  } else if (x == yNext) {
15726 
15727  size = cuddSwapInPlace(table,x,xNext);
15728  if (size == 0) goto ddSwapAnyOutOfMem;
15729  move = (Move *) cuddDynamicAllocNode(table);
15730  if (move == NULL) goto ddSwapAnyOutOfMem;
15731  move->x = x;
15732  move->y = xNext;
15733  move->size = size;
15734  move->next = moves;
15735  moves = move;
15736 
15737  tmp = x; x = y; y = tmp;
15738 
15739  } else {
15740  size = cuddSwapInPlace(table,x,xNext);
15741  if (size == 0) goto ddSwapAnyOutOfMem;
15742  move = (Move *) cuddDynamicAllocNode(table);
15743  if (move == NULL) goto ddSwapAnyOutOfMem;
15744  move->x = x;
15745  move->y = xNext;
15746  move->size = size;
15747  move->next = moves;
15748  moves = move;
15749 
15750  size = cuddSwapInPlace(table,yNext,y);
15751  if (size == 0) goto ddSwapAnyOutOfMem;
15752  move = (Move *) cuddDynamicAllocNode(table);
15753  if (move == NULL) goto ddSwapAnyOutOfMem;
15754  move->x = yNext;
15755  move->y = y;
15756  move->size = size;
15757  move->next = moves;
15758  moves = move;
15759 
15760  x = xNext;
15761  y = yNext;
15762  }
15763 
15764  xNext = cuddNextHigh(table,x);
15765  yNext = cuddNextLow(table,y);
15766  if (xNext > yRef) break;
15767 
15768  if ((double) size > table->maxGrowth * (double) limitSize) break;
15769  if (size < limitSize) limitSize = size;
15770  }
15771  if (yNext>=xRef) {
15772  size = cuddSwapInPlace(table,yNext,y);
15773  if (size == 0) goto ddSwapAnyOutOfMem;
15774  move = (Move *) cuddDynamicAllocNode(table);
15775  if (move == NULL) goto ddSwapAnyOutOfMem;
15776  move->x = yNext;
15777  move->y = y;
15778  move->size = size;
15779  move->next = moves;
15780  moves = move;
15781  }
15782 
15783  return(moves);
15784 
15785  ddSwapAnyOutOfMem:
15786  while (moves != NULL) {
15787  move = moves->next;
15788  cuddDeallocMove(table, moves);
15789  moves = move;
15790  }
15791  return(NULL);
15792 
15793 } /* end of ddSwapAny */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
unsigned int keys
Definition: cuddInt.h:353
DdHalfWord x
Definition: cuddInt.h:470
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
int isolated
Definition: cuddInt.h:368
int size
Definition: cuddInt.h:473

◆ ddSymmGroupMove()

static int ddSymmGroupMove ( DdManager table,
int  x,
int  y,
Move **  moves 
)
static

Function********************************************************************

Synopsis [Swaps two groups.]

Description [Swaps two groups. x is assumed to be the bottom variable of the first group. y is assumed to be the top variable of the second group. Updates the list of moves. Returns the number of keys in the table if successful; 0 otherwise.]

SideEffects [None]

Definition at line 19204 of file cuddInt.c.

19209 {
19210 Move *move;
19211 int size;
19212 int i,j;
19213 int xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
19214 int swapx,swapy;
19215 
19216 #ifdef DD_DEBUG
19217 assert(x < y); /* we assume that x < y */
19218 #endif
19219 /* Find top, bottom, and size for the two groups. */
19220 xbot = x;
19221 xtop = table->subtables[x].next;
19222 xsize = xbot - xtop + 1;
19223 ybot = y;
19224 while ((unsigned) ybot < table->subtables[ybot].next)
19225 ybot = table->subtables[ybot].next;
19226 ytop = y;
19227 ysize = ybot - ytop + 1;
19228 
19229 /* Sift the variables of the second group up through the first group. */
19230 for (i = 1; i <= ysize; i++) {
19231 for (j = 1; j <= xsize; j++) {
19232 size = cuddSwapInPlace(table,x,y);
19233 if (size == 0) return(0);
19234 swapx = x; swapy = y;
19235 y = x;
19236 x = y - 1;
19237 }
19238 y = ytop + i;
19239 x = y - 1;
19240 }
19241 
19242 /* fix symmetries */
19243 y = xtop; /* ytop is now where xtop used to be */
19244 for (i = 0; i < ysize-1 ; i++) {
19245 table->subtables[y].next = y + 1;
19246 y = y + 1;
19247 }
19248 table->subtables[y].next = xtop; /* y is bottom of its group, join */
19249 /* its symmetry to top of its group */
19250 x = y + 1;
19251 newxtop = x;
19252 for (i = 0; i < xsize - 1 ; i++) {
19253 table->subtables[x].next = x + 1;
19254 x = x + 1;
19255 }
19256 table->subtables[x].next = newxtop; /* x is bottom of its group, join */
19257 /* its symmetry to top of its group */
19258 /* Store group move */
19259 move = (Move *) cuddDynamicAllocNode(table);
19260 if (move == NULL) return(0);
19261 move->x = swapx;
19262 move->y = swapy;
19263 move->size = size;
19264 move->next = *moves;
19265 *moves = move;
19266 
19267 return(size);
19268 
19269 } /* end of ddSymmGroupMove */
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
DdHalfWord x
Definition: cuddInt.h:470
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473

◆ ddSymmGroupMoveBackward()

static int ddSymmGroupMoveBackward ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [Undoes the swap of two groups.]

Description [Undoes the swap of two groups. x is assumed to be the bottom variable of the first group. y is assumed to be the top variable of the second group. Returns the number of keys in the table if successful; 0 otherwise.]

SideEffects [None]

Definition at line 19285 of file cuddInt.c.

19289 {
19290 int size;
19291 int i,j;
19292 int xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
19293 
19294 #ifdef DD_DEBUG
19295 assert(x < y); /* We assume that x < y */
19296 #endif
19297 
19298 /* Find top, bottom, and size for the two groups. */
19299 xbot = x;
19300 xtop = table->subtables[x].next;
19301 xsize = xbot - xtop + 1;
19302 ybot = y;
19303 while ((unsigned) ybot < table->subtables[ybot].next)
19304 ybot = table->subtables[ybot].next;
19305 ytop = y;
19306 ysize = ybot - ytop + 1;
19307 
19308 /* Sift the variables of the second group up through the first group. */
19309 for (i = 1; i <= ysize; i++) {
19310 for (j = 1; j <= xsize; j++) {
19311 size = cuddSwapInPlace(table,x,y);
19312 if (size == 0) return(0);
19313 y = x;
19314 x = cuddNextLow(table,y);
19315 }
19316 y = ytop + i;
19317 x = y - 1;
19318 }
19319 
19320 /* Fix symmetries. */
19321 y = xtop;
19322 for (i = 0; i < ysize-1 ; i++) {
19323 table->subtables[y].next = y + 1;
19324 y = y + 1;
19325 }
19326 table->subtables[y].next = xtop; /* y is bottom of its group, join */
19327 /* its symmetry to top of its group */
19328 x = y + 1;
19329 newxtop = x;
19330 for (i = 0; i < xsize-1 ; i++) {
19331 table->subtables[x].next = x + 1;
19332 x = x + 1;
19333 }
19334 table->subtables[x].next = newxtop; /* x is bottom of its group, join */
19335 /* its symmetry to top of its group */
19336 
19337 return(size);
19338 
19339 } /* end of ddSymmGroupMoveBackward */
#define assert(ex)
Definition: util.h:141
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
unsigned int next
Definition: cuddInt.h:317

◆ ddSymmSiftingAux()

static int ddSymmSiftingAux ( DdManager table,
int  x,
int  xLow,
int  xHigh 
)
static

Function********************************************************************

Synopsis [Given xLow <= x <= xHigh moves x up and down between the boundaries.]

Description [Given xLow <= x <= xHigh moves x up and down between the boundaries. Finds the best position and does the required changes. Assumes that x is not part of a symmetry group. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 18365 of file cuddInt.c.

18370 {
18371 Move *move;
18372 Move *moveUp; /* list of up moves */
18373 Move *moveDown; /* list of down moves */
18374 int initialSize;
18375 int result;
18376 int i;
18377 int topbot; /* index to either top or bottom of symmetry group */
18378 int initGroupSize, finalGroupSize;
18379 
18380 
18381 #ifdef DD_DEBUG
18382 /* check for previously detected symmetry */
18383 assert(table->subtables[x].next == (unsigned) x);
18384 #endif
18385 
18386 initialSize = table->keys - table->isolated;
18387 
18388 moveDown = NULL;
18389 moveUp = NULL;
18390 
18391 if ((x - xLow) > (xHigh - x)) {
18392 /* Will go down first, unless x == xHigh:
18393 ** Look for consecutive symmetries above x.
18394 */
18395 for (i = x; i > xLow; i--) {
18396 if (!cuddSymmCheck(table,i-1,i))
18397 break;
18398 topbot = table->subtables[i-1].next; /* find top of i-1's group */
18399 table->subtables[i-1].next = i;
18400 table->subtables[x].next = topbot; /* x is bottom of group so its */
18401 /* next is top of i-1's group */
18402 i = topbot + 1; /* add 1 for i--; new i is top of symm group */
18403 }
18404 } else {
18405 /* Will go up first unless x == xlow:
18406 ** Look for consecutive symmetries below x.
18407 */
18408 for (i = x; i < xHigh; i++) {
18409 if (!cuddSymmCheck(table,i,i+1))
18410 break;
18411 /* find bottom of i+1's symm group */
18412 topbot = i + 1;
18413 while ((unsigned) topbot < table->subtables[topbot].next) {
18414 topbot = table->subtables[topbot].next;
18415 }
18416 table->subtables[topbot].next = table->subtables[i].next;
18417 table->subtables[i].next = i + 1;
18418 i = topbot - 1; /* subtract 1 for i++; new i is bottom of group */
18419 }
18420 }
18421 
18422 /* Now x may be in the middle of a symmetry group.
18423 ** Find bottom of x's symm group.
18424 */
18425 while ((unsigned) x < table->subtables[x].next)
18426 x = table->subtables[x].next;
18427 
18428 if (x == xLow) { /* Sift down */
18429 
18430 #ifdef DD_DEBUG
18431 /* x must be a singleton */
18432 assert((unsigned) x == table->subtables[x].next);
18433 #endif
18434 if (x == xHigh) return(1); /* just one variable */
18435 
18436 initGroupSize = 1;
18437 
18438 moveDown = ddSymmSiftingDown(table,x,xHigh);
18439 /* after this point x --> xHigh, unless early term */
18440 if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem;
18441 if (moveDown == NULL) return(1);
18442 
18443 x = moveDown->y;
18444 /* Find bottom of x's group */
18445 i = x;
18446 while ((unsigned) i < table->subtables[i].next) {
18447 i = table->subtables[i].next;
18448 }
18449 #ifdef DD_DEBUG
18450 /* x should be the top of the symmetry group and i the bottom */
18451 assert((unsigned) i >= table->subtables[i].next);
18452 assert((unsigned) x == table->subtables[i].next);
18453 #endif
18454 finalGroupSize = i - x + 1;
18455 
18456 if (initGroupSize == finalGroupSize) {
18457 /* No new symmetry groups detected, return to best position */
18458 result = ddSymmSiftingBackward(table,moveDown,initialSize);
18459 } else {
18460 initialSize = table->keys - table->isolated;
18461 moveUp = ddSymmSiftingUp(table,x,xLow);
18462 result = ddSymmSiftingBackward(table,moveUp,initialSize);
18463 }
18464 if (!result) goto ddSymmSiftingAuxOutOfMem;
18465 
18466 } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */
18467 /* Find top of x's symm group */
18468 i = x; /* bottom */
18469 x = table->subtables[x].next; /* top */
18470 
18471 if (x == xLow) return(1); /* just one big group */
18472 
18473 initGroupSize = i - x + 1;
18474 
18475 moveUp = ddSymmSiftingUp(table,x,xLow);
18476 /* after this point x --> xLow, unless early term */
18477 if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem;
18478 if (moveUp == NULL) return(1);
18479 
18480 x = moveUp->x;
18481 /* Find top of x's group */
18482 i = table->subtables[x].next;
18483 #ifdef DD_DEBUG
18484 /* x should be the bottom of the symmetry group and i the top */
18485 assert((unsigned) x >= table->subtables[x].next);
18486 assert((unsigned) i == table->subtables[x].next);
18487 #endif
18488 finalGroupSize = x - i + 1;
18489 
18490 if (initGroupSize == finalGroupSize) {
18491 /* No new symmetry groups detected, return to best position */
18492 result = ddSymmSiftingBackward(table,moveUp,initialSize);
18493 } else {
18494 initialSize = table->keys - table->isolated;
18495 moveDown = ddSymmSiftingDown(table,x,xHigh);
18496 result = ddSymmSiftingBackward(table,moveDown,initialSize);
18497 }
18498 if (!result) goto ddSymmSiftingAuxOutOfMem;
18499 
18500 } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */
18501 
18502 moveDown = ddSymmSiftingDown(table,x,xHigh);
18503 /* at this point x == xHigh, unless early term */
18504 if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem;
18505 
18506 if (moveDown != NULL) {
18507 x = moveDown->y; /* x is top here */
18508 i = x;
18509 while ((unsigned) i < table->subtables[i].next) {
18510 i = table->subtables[i].next;
18511 }
18512 } else {
18513 i = x;
18514 while ((unsigned) i < table->subtables[i].next) {
18515 i = table->subtables[i].next;
18516 }
18517 x = table->subtables[i].next;
18518 }
18519 #ifdef DD_DEBUG
18520 /* x should be the top of the symmetry group and i the bottom */
18521 assert((unsigned) i >= table->subtables[i].next);
18522 assert((unsigned) x == table->subtables[i].next);
18523 #endif
18524 initGroupSize = i - x + 1;
18525 
18526 moveUp = ddSymmSiftingUp(table,x,xLow);
18527 if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem;
18528 
18529 if (moveUp != NULL) {
18530 x = moveUp->x;
18531 i = table->subtables[x].next;
18532 } else {
18533 i = x;
18534 while ((unsigned) x < table->subtables[x].next)
18535 x = table->subtables[x].next;
18536 }
18537 #ifdef DD_DEBUG
18538 /* x should be the bottom of the symmetry group and i the top */
18539 assert((unsigned) x >= table->subtables[x].next);
18540 assert((unsigned) i == table->subtables[x].next);
18541 #endif
18542 finalGroupSize = x - i + 1;
18543 
18544 if (initGroupSize == finalGroupSize) {
18545 /* No new symmetry groups detected, return to best position */
18546 result = ddSymmSiftingBackward(table,moveUp,initialSize);
18547 } else {
18548 while (moveDown != NULL) {
18549 move = moveDown->next;
18550 cuddDeallocMove(table, moveDown);
18551 moveDown = move;
18552 }
18553 initialSize = table->keys - table->isolated;
18554 moveDown = ddSymmSiftingDown(table,x,xHigh);
18555 result = ddSymmSiftingBackward(table,moveDown,initialSize);
18556 }
18557 if (!result) goto ddSymmSiftingAuxOutOfMem;
18558 
18559 } else { /* moving up first: shorter */
18560 /* Find top of x's symmetry group */
18561 x = table->subtables[x].next;
18562 
18563 moveUp = ddSymmSiftingUp(table,x,xLow);
18564 /* at this point x == xHigh, unless early term */
18565 if (moveUp == MV_OOM) goto ddSymmSiftingAuxOutOfMem;
18566 
18567 if (moveUp != NULL) {
18568 x = moveUp->x;
18569 i = table->subtables[x].next;
18570 } else {
18571 while ((unsigned) x < table->subtables[x].next)
18572 x = table->subtables[x].next;
18573 i = table->subtables[x].next;
18574 }
18575 #ifdef DD_DEBUG
18576 /* x is bottom of the symmetry group and i is top */
18577 assert((unsigned) x >= table->subtables[x].next);
18578 assert((unsigned) i == table->subtables[x].next);
18579 #endif
18580 initGroupSize = x - i + 1;
18581 
18582 moveDown = ddSymmSiftingDown(table,x,xHigh);
18583 if (moveDown == MV_OOM) goto ddSymmSiftingAuxOutOfMem;
18584 
18585 if (moveDown != NULL) {
18586 x = moveDown->y;
18587 i = x;
18588 while ((unsigned) i < table->subtables[i].next) {
18589 i = table->subtables[i].next;
18590 }
18591 } else {
18592 i = x;
18593 x = table->subtables[x].next;
18594 }
18595 #ifdef DD_DEBUG
18596 /* x should be the top of the symmetry group and i the bottom */
18597 assert((unsigned) i >= table->subtables[i].next);
18598 assert((unsigned) x == table->subtables[i].next);
18599 #endif
18600 finalGroupSize = i - x + 1;
18601 
18602 if (initGroupSize == finalGroupSize) {
18603 /* No new symmetries detected, go back to best position */
18604 result = ddSymmSiftingBackward(table,moveDown,initialSize);
18605 } else {
18606 while (moveUp != NULL) {
18607 move = moveUp->next;
18608 cuddDeallocMove(table, moveUp);
18609 moveUp = move;
18610 }
18611 initialSize = table->keys - table->isolated;
18612 moveUp = ddSymmSiftingUp(table,x,xLow);
18613 result = ddSymmSiftingBackward(table,moveUp,initialSize);
18614 }
18615 if (!result) goto ddSymmSiftingAuxOutOfMem;
18616 }
18617 
18618 while (moveDown != NULL) {
18619 move = moveDown->next;
18620 cuddDeallocMove(table, moveDown);
18621 moveDown = move;
18622 }
18623 while (moveUp != NULL) {
18624 move = moveUp->next;
18625 cuddDeallocMove(table, moveUp);
18626 moveUp = move;
18627 }
18628 
18629 return(1);
18630 
18631 ddSymmSiftingAuxOutOfMem:
18632 if (moveDown != MV_OOM) {
18633 while (moveDown != NULL) {
18634 move = moveDown->next;
18635 cuddDeallocMove(table, moveDown);
18636 moveDown = move;
18637 }
18638 }
18639 if (moveUp != MV_OOM) {
18640 while (moveUp != NULL) {
18641 move = moveUp->next;
18642 cuddDeallocMove(table, moveUp);
18643 moveUp = move;
18644 }
18645 }
18646 
18647 return(0);
18648 
18649 } /* end of ddSymmSiftingAux */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdSubtable * subtables
Definition: cuddInt.h:349
#define MV_OOM
Definition: cuddInt.c:17842
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
unsigned int keys
Definition: cuddInt.h:353
DdHalfWord x
Definition: cuddInt.h:470
static Move * ddSymmSiftingDown(DdManager *table, int x, int xHigh)
Definition: cuddInt.c:19066
static Move * ddSymmSiftingUp(DdManager *table, int y, int xLow)
Definition: cuddInt.c:18924
static int ddSymmSiftingBackward(DdManager *table, Move *moves, int size)
Definition: cuddInt.c:19356
int cuddSymmCheck(DdManager *table, int x, int y)
Definition: cuddInt.c:17912
static int result
Definition: cuddInt.c:7466
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int isolated
Definition: cuddInt.h:368

◆ ddSymmSiftingBackward()

static int ddSymmSiftingBackward ( DdManager table,
Move moves,
int  size 
)
static

Function********************************************************************

Synopsis [Given a set of moves, returns the DD heap to the position giving the minimum size.]

Description [Given a set of moves, returns the DD heap to the position giving the minimum size. In case of ties, returns to the closest position giving the minimum size. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 19356 of file cuddInt.c.

19360 {
19361 Move *move;
19362 int res;
19363 
19364 for (move = moves; move != NULL; move = move->next) {
19365 if (move->size < size) {
19366 size = move->size;
19367 }
19368 }
19369 
19370 for (move = moves; move != NULL; move = move->next) {
19371 if (move->size == size) return(1);
19372 if (table->subtables[move->x].next == move->x && table->subtables[move->y].next == move->y) {
19373 res = cuddSwapInPlace(table,(int)move->x,(int)move->y);
19374 #ifdef DD_DEBUG
19375 assert(table->subtables[move->x].next == move->x);
19376 assert(table->subtables[move->y].next == move->y);
19377 #endif
19378 } else { /* Group move necessary */
19379 res = ddSymmGroupMoveBackward(table,(int)move->x,(int)move->y);
19380 }
19381 if (!res) return(0);
19382 }
19383 
19384 return(1);
19385 
19386 } /* end of ddSymmSiftingBackward */
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
DdHalfWord x
Definition: cuddInt.h:470
DdHalfWord y
Definition: cuddInt.h:471
static int ddSymmGroupMoveBackward(DdManager *table, int x, int y)
Definition: cuddInt.c:19285
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473

◆ ddSymmSiftingConvAux()

static int ddSymmSiftingConvAux ( DdManager table,
int  x,
int  xLow,
int  xHigh 
)
static

Function********************************************************************

Synopsis [Given xLow <= x <= xHigh moves x up and down between the boundaries.]

Description [Given xLow <= x <= xHigh moves x up and down between the boundaries. Finds the best position and does the required changes. Assumes that x is either an isolated variable, or it is the bottom of a symmetry group. All symmetries may not have been found, because of exceeded growth limit. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 18667 of file cuddInt.c.

18672 {
18673 Move *move;
18674 Move *moveUp; /* list of up moves */
18675 Move *moveDown; /* list of down moves */
18676 int initialSize;
18677 int result;
18678 int i;
18679 int initGroupSize, finalGroupSize;
18680 
18681 
18682 initialSize = table->keys - table->isolated;
18683 
18684 moveDown = NULL;
18685 moveUp = NULL;
18686 
18687 if (x == xLow) { /* Sift down */
18688 #ifdef DD_DEBUG
18689 /* x is bottom of symmetry group */
18690 assert((unsigned) x >= table->subtables[x].next);
18691 #endif
18692 i = table->subtables[x].next;
18693 initGroupSize = x - i + 1;
18694 
18695 moveDown = ddSymmSiftingDown(table,x,xHigh);
18696 /* at this point x == xHigh, unless early term */
18697 if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem;
18698 if (moveDown == NULL) return(1);
18699 
18700 x = moveDown->y;
18701 i = x;
18702 while ((unsigned) i < table->subtables[i].next) {
18703 i = table->subtables[i].next;
18704 }
18705 #ifdef DD_DEBUG
18706 /* x should be the top of the symmetric group and i the bottom */
18707 assert((unsigned) i >= table->subtables[i].next);
18708 assert((unsigned) x == table->subtables[i].next);
18709 #endif
18710 finalGroupSize = i - x + 1;
18711 
18712 if (initGroupSize == finalGroupSize) {
18713 /* No new symmetries detected, go back to best position */
18714 result = ddSymmSiftingBackward(table,moveDown,initialSize);
18715 } else {
18716 initialSize = table->keys - table->isolated;
18717 moveUp = ddSymmSiftingUp(table,x,xLow);
18718 result = ddSymmSiftingBackward(table,moveUp,initialSize);
18719 }
18720 if (!result) goto ddSymmSiftingConvAuxOutOfMem;
18721 
18722 } else if (cuddNextHigh(table,x) > xHigh) { /* Sift up */
18723 /* Find top of x's symm group */
18724 while ((unsigned) x < table->subtables[x].next)
18725 x = table->subtables[x].next;
18726 i = x; /* bottom */
18727 x = table->subtables[x].next; /* top */
18728 
18729 if (x == xLow) return(1);
18730 
18731 initGroupSize = i - x + 1;
18732 
18733 moveUp = ddSymmSiftingUp(table,x,xLow);
18734 /* at this point x == xLow, unless early term */
18735 if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem;
18736 if (moveUp == NULL) return(1);
18737 
18738 x = moveUp->x;
18739 i = table->subtables[x].next;
18740 #ifdef DD_DEBUG
18741 /* x should be the bottom of the symmetry group and i the top */
18742 assert((unsigned) x >= table->subtables[x].next);
18743 assert((unsigned) i == table->subtables[x].next);
18744 #endif
18745 finalGroupSize = x - i + 1;
18746 
18747 if (initGroupSize == finalGroupSize) {
18748 /* No new symmetry groups detected, return to best position */
18749 result = ddSymmSiftingBackward(table,moveUp,initialSize);
18750 } else {
18751 initialSize = table->keys - table->isolated;
18752 moveDown = ddSymmSiftingDown(table,x,xHigh);
18753 result = ddSymmSiftingBackward(table,moveDown,initialSize);
18754 }
18755 if (!result)
18756 goto ddSymmSiftingConvAuxOutOfMem;
18757 
18758 } else if ((x - xLow) > (xHigh - x)) { /* must go down first: shorter */
18759 moveDown = ddSymmSiftingDown(table,x,xHigh);
18760 /* at this point x == xHigh, unless early term */
18761 if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem;
18762 
18763 if (moveDown != NULL) {
18764 x = moveDown->y;
18765 i = x;
18766 while ((unsigned) i < table->subtables[i].next) {
18767 i = table->subtables[i].next;
18768 }
18769 } else {
18770 while ((unsigned) x < table->subtables[x].next)
18771 x = table->subtables[x].next;
18772 i = x;
18773 x = table->subtables[x].next;
18774 }
18775 #ifdef DD_DEBUG
18776 /* x should be the top of the symmetry group and i the bottom */
18777 assert((unsigned) i >= table->subtables[i].next);
18778 assert((unsigned) x == table->subtables[i].next);
18779 #endif
18780 initGroupSize = i - x + 1;
18781 
18782 moveUp = ddSymmSiftingUp(table,x,xLow);
18783 if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem;
18784 
18785 if (moveUp != NULL) {
18786 x = moveUp->x;
18787 i = table->subtables[x].next;
18788 } else {
18789 i = x;
18790 while ((unsigned) x < table->subtables[x].next)
18791 x = table->subtables[x].next;
18792 }
18793 #ifdef DD_DEBUG
18794 /* x should be the bottom of the symmetry group and i the top */
18795 assert((unsigned) x >= table->subtables[x].next);
18796 assert((unsigned) i == table->subtables[x].next);
18797 #endif
18798 finalGroupSize = x - i + 1;
18799 
18800 if (initGroupSize == finalGroupSize) {
18801 /* No new symmetry groups detected, return to best position */
18802 result = ddSymmSiftingBackward(table,moveUp,initialSize);
18803 } else {
18804 while (moveDown != NULL) {
18805 move = moveDown->next;
18806 cuddDeallocMove(table, moveDown);
18807 moveDown = move;
18808 }
18809 initialSize = table->keys - table->isolated;
18810 moveDown = ddSymmSiftingDown(table,x,xHigh);
18811 result = ddSymmSiftingBackward(table,moveDown,initialSize);
18812 }
18813 if (!result) goto ddSymmSiftingConvAuxOutOfMem;
18814 
18815 } else { /* moving up first: shorter */
18816 /* Find top of x's symmetry group */
18817 x = table->subtables[x].next;
18818 
18819 moveUp = ddSymmSiftingUp(table,x,xLow);
18820 /* at this point x == xHigh, unless early term */
18821 if (moveUp == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem;
18822 
18823 if (moveUp != NULL) {
18824 x = moveUp->x;
18825 i = table->subtables[x].next;
18826 } else {
18827 i = x;
18828 while ((unsigned) x < table->subtables[x].next)
18829 x = table->subtables[x].next;
18830 }
18831 #ifdef DD_DEBUG
18832 /* x is bottom of the symmetry group and i is top */
18833 assert((unsigned) x >= table->subtables[x].next);
18834 assert((unsigned) i == table->subtables[x].next);
18835 #endif
18836 initGroupSize = x - i + 1;
18837 
18838 moveDown = ddSymmSiftingDown(table,x,xHigh);
18839 if (moveDown == MV_OOM) goto ddSymmSiftingConvAuxOutOfMem;
18840 
18841 if (moveDown != NULL) {
18842 x = moveDown->y;
18843 i = x;
18844 while ((unsigned) i < table->subtables[i].next) {
18845 i = table->subtables[i].next;
18846 }
18847 } else {
18848 i = x;
18849 x = table->subtables[x].next;
18850 }
18851 #ifdef DD_DEBUG
18852 /* x should be the top of the symmetry group and i the bottom */
18853 assert((unsigned) i >= table->subtables[i].next);
18854 assert((unsigned) x == table->subtables[i].next);
18855 #endif
18856 finalGroupSize = i - x + 1;
18857 
18858 if (initGroupSize == finalGroupSize) {
18859 /* No new symmetries detected, go back to best position */
18860 result = ddSymmSiftingBackward(table,moveDown,initialSize);
18861 } else {
18862 while (moveUp != NULL) {
18863 move = moveUp->next;
18864 cuddDeallocMove(table, moveUp);
18865 moveUp = move;
18866 }
18867 initialSize = table->keys - table->isolated;
18868 moveUp = ddSymmSiftingUp(table,x,xLow);
18869 result = ddSymmSiftingBackward(table,moveUp,initialSize);
18870 }
18871 if (!result) goto ddSymmSiftingConvAuxOutOfMem;
18872 }
18873 
18874 while (moveDown != NULL) {
18875 move = moveDown->next;
18876 cuddDeallocMove(table, moveDown);
18877 moveDown = move;
18878 }
18879 while (moveUp != NULL) {
18880 move = moveUp->next;
18881 cuddDeallocMove(table, moveUp);
18882 moveUp = move;
18883 }
18884 
18885 return(1);
18886 
18887 ddSymmSiftingConvAuxOutOfMem:
18888 if (moveDown != MV_OOM) {
18889 while (moveDown != NULL) {
18890 move = moveDown->next;
18891 cuddDeallocMove(table, moveDown);
18892 moveDown = move;
18893 }
18894 }
18895 if (moveUp != MV_OOM) {
18896 while (moveUp != NULL) {
18897 move = moveUp->next;
18898 cuddDeallocMove(table, moveUp);
18899 moveUp = move;
18900 }
18901 }
18902 
18903 return(0);
18904 
18905 } /* end of ddSymmSiftingConvAux */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdSubtable * subtables
Definition: cuddInt.h:349
#define MV_OOM
Definition: cuddInt.c:17842
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
unsigned int keys
Definition: cuddInt.h:353
DdHalfWord x
Definition: cuddInt.h:470
static Move * ddSymmSiftingDown(DdManager *table, int x, int xHigh)
Definition: cuddInt.c:19066
static Move * ddSymmSiftingUp(DdManager *table, int y, int xLow)
Definition: cuddInt.c:18924
static int ddSymmSiftingBackward(DdManager *table, Move *moves, int size)
Definition: cuddInt.c:19356
static int result
Definition: cuddInt.c:7466
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int isolated
Definition: cuddInt.h:368

◆ ddSymmSiftingDown()

static Move * ddSymmSiftingDown ( DdManager table,
int  x,
int  xHigh 
)
static

Function********************************************************************

Synopsis [Moves x down until either it reaches the bound (xHigh) or the size of the DD heap increases too much.]

Description [Moves x down until either it reaches the bound (xHigh) or the size of the DD heap increases too much. Assumes that x is the bottom of a symmetry group. Checks x for symmetry to the adjacent variables. If symmetry is found, the symmetry group of x is merged with the symmetry group of the other variable. Returns the set of moves in case of success; MV_OOM if memory is full.]

SideEffects [None]

Definition at line 19066 of file cuddInt.c.

19070 {
19071 Move *moves;
19072 Move *move;
19073 int y;
19074 int size;
19075 int limitSize;
19076 int gxtop,gybot;
19077 int R; /* upper bound on node decrease */
19078 int xindex, yindex;
19079 int isolated;
19080 int z;
19081 int zindex;
19082 #ifdef DD_DEBUG
19083 int checkR;
19084 #endif
19085 
19086 moves = NULL;
19087 /* Initialize R */
19088 xindex = table->invperm[x];
19089 gxtop = table->subtables[x].next;
19090 limitSize = size = table->keys - table->isolated;
19091 R = 0;
19092 for (z = xHigh; z > gxtop; z--) {
19093 zindex = table->invperm[z];
19094 if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) {
19095 isolated = table->vars[zindex]->ref == 1;
19096 R += table->subtables[z].keys - isolated;
19097 }
19098 }
19099 
19100 y = cuddNextHigh(table,x);
19101 while (y <= xHigh && size - R < limitSize) {
19102 #ifdef DD_DEBUG
19103 gxtop = table->subtables[x].next;
19104 checkR = 0;
19105 for (z = xHigh; z > gxtop; z--) {
19106 zindex = table->invperm[z];
19107 if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) {
19108 isolated = table->vars[zindex]->ref == 1;
19109 checkR += table->subtables[z].keys - isolated;
19110 }
19111 }
19112 assert(R == checkR);
19113 #endif
19114 gybot = table->subtables[y].next;
19115 while (table->subtables[gybot].next != (unsigned) y)
19116 gybot = table->subtables[gybot].next;
19117 if (cuddSymmCheck(table,x,y)) {
19118 /* Symmetry found, attach symm groups */
19119 gxtop = table->subtables[x].next;
19120 table->subtables[x].next = y;
19121 table->subtables[gybot].next = gxtop;
19122 } else if (table->subtables[x].next == (unsigned) x &&
19123 table->subtables[y].next == (unsigned) y) {
19124 /* x and y have self symmetry */
19125 /* Update upper bound on node decrease. */
19126 yindex = table->invperm[y];
19127 if (cuddTestInteract(table,xindex,yindex)) {
19128 isolated = table->vars[yindex]->ref == 1;
19129 R -= table->subtables[y].keys - isolated;
19130 }
19131 size = cuddSwapInPlace(table,x,y);
19132 #ifdef DD_DEBUG
19133 assert(table->subtables[x].next == (unsigned) x);
19134 assert(table->subtables[y].next == (unsigned) y);
19135 #endif
19136 if (size == 0) goto ddSymmSiftingDownOutOfMem;
19137 move = (Move *) cuddDynamicAllocNode(table);
19138 if (move == NULL) goto ddSymmSiftingDownOutOfMem;
19139 move->x = x;
19140 move->y = y;
19141 move->size = size;
19142 move->next = moves;
19143 moves = move;
19144 if ((double) size > (double) limitSize * table->maxGrowth)
19145 return(moves);
19146 if (size < limitSize) limitSize = size;
19147 } else { /* Group move */
19148 /* Update upper bound on node decrease: first phase. */
19149 gxtop = table->subtables[x].next;
19150 z = gxtop + 1;
19151 do {
19152 zindex = table->invperm[z];
19153 if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) {
19154 isolated = table->vars[zindex]->ref == 1;
19155 R -= table->subtables[z].keys - isolated;
19156 }
19157 z++;
19158 } while (z <= gybot);
19159 size = ddSymmGroupMove(table,x,y,&moves);
19160 if (size == 0) goto ddSymmSiftingDownOutOfMem;
19161 if ((double) size > (double) limitSize * table->maxGrowth)
19162 return(moves);
19163 if (size < limitSize) limitSize = size;
19164 /* Update upper bound on node decrease: second phase. */
19165 gxtop = table->subtables[gybot].next;
19166 for (z = gxtop + 1; z <= gybot; z++) {
19167 zindex = table->invperm[z];
19168 if (zindex == xindex || cuddTestInteract(table,xindex,zindex)) {
19169 isolated = table->vars[zindex]->ref == 1;
19170 R += table->subtables[z].keys - isolated;
19171 }
19172 }
19173 }
19174 x = gybot;
19175 y = cuddNextHigh(table,x);
19176 }
19177 
19178 return(moves);
19179 
19180 ddSymmSiftingDownOutOfMem:
19181 while (moves != NULL) {
19182 move = moves->next;
19183 cuddDeallocMove(table, moves);
19184 moves = move;
19185 }
19186 return(MV_OOM);
19187 
19188 } /* end of ddSymmSiftingDown */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
static int ddSymmGroupMove(DdManager *table, int x, int y, Move **moves)
Definition: cuddInt.c:19204
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
#define MV_OOM
Definition: cuddInt.c:17842
int cuddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:15037
unsigned int keys
Definition: cuddInt.h:353
DdHalfWord x
Definition: cuddInt.h:470
int cuddSymmCheck(DdManager *table, int x, int y)
Definition: cuddInt.c:17912
DdHalfWord y
Definition: cuddInt.h:471
DdNode ** vars
Definition: cuddInt.h:373
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int size
Definition: cuddInt.h:473

◆ ddSymmSiftingUp()

static Move * ddSymmSiftingUp ( DdManager table,
int  y,
int  xLow 
)
static

Function********************************************************************

Synopsis [Moves x up until either it reaches the bound (xLow) or the size of the DD heap increases too much.]

Description [Moves x up until either it reaches the bound (xLow) or the size of the DD heap increases too much. Assumes that x is the top of a symmetry group. Checks x for symmetry to the adjacent variables. If symmetry is found, the symmetry group of x is merged with the symmetry group of the other variable. Returns the set of moves in case of success; MV_OOM if memory is full.]

SideEffects [None]

Definition at line 18924 of file cuddInt.c.

18928 {
18929 Move *moves;
18930 Move *move;
18931 int x;
18932 int size;
18933 int i;
18934 int gxtop,gybot;
18935 int limitSize;
18936 int xindex, yindex;
18937 int zindex;
18938 int z;
18939 int isolated;
18940 int L; /* lower bound on DD size */
18941 #ifdef DD_DEBUG
18942 int checkL;
18943 #endif
18944 
18945 
18946 moves = NULL;
18947 yindex = table->invperm[y];
18948 
18949 /* Initialize the lower bound.
18950 ** The part of the DD below the bottom of y' group will not change.
18951 ** The part of the DD above y that does not interact with y will not
18952 ** change. The rest may vanish in the best case, except for
18953 ** the nodes at level xLow, which will not vanish, regardless.
18954 */
18955 limitSize = L = table->keys - table->isolated;
18956 gybot = y;
18957 while ((unsigned) gybot < table->subtables[gybot].next)
18958 gybot = table->subtables[gybot].next;
18959 for (z = xLow + 1; z <= gybot; z++) {
18960 zindex = table->invperm[z];
18961 if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) {
18962 isolated = table->vars[zindex]->ref == 1;
18963 L -= table->subtables[z].keys - isolated;
18964 }
18965 }
18966 
18967 x = cuddNextLow(table,y);
18968 while (x >= xLow && L <= limitSize) {
18969 #ifdef DD_DEBUG
18970 gybot = y;
18971 while ((unsigned) gybot < table->subtables[gybot].next)
18972 gybot = table->subtables[gybot].next;
18973 checkL = table->keys - table->isolated;
18974 for (z = xLow + 1; z <= gybot; z++) {
18975 zindex = table->invperm[z];
18976 if (zindex == yindex || cuddTestInteract(table,zindex,yindex)) {
18977 isolated = table->vars[zindex]->ref == 1;
18978 checkL -= table->subtables[z].keys - isolated;
18979 }
18980 }
18981 assert(L == checkL);
18982 #endif
18983 gxtop = table->subtables[x].next;
18984 if (cuddSymmCheck(table,x,y)) {
18985 /* Symmetry found, attach symm groups */
18986 table->subtables[x].next = y;
18987 i = table->subtables[y].next;
18988 while (table->subtables[i].next != (unsigned) y)
18989 i = table->subtables[i].next;
18990 table->subtables[i].next = gxtop;
18991 } else if (table->subtables[x].next == (unsigned) x &&
18992 table->subtables[y].next == (unsigned) y) {
18993 /* x and y have self symmetry */
18994 xindex = table->invperm[x];
18995 size = cuddSwapInPlace(table,x,y);
18996 #ifdef DD_DEBUG
18997 assert(table->subtables[x].next == (unsigned) x);
18998 assert(table->subtables[y].next == (unsigned) y);
18999 #endif
19000 if (size == 0) goto ddSymmSiftingUpOutOfMem;
19001 /* Update the lower bound. */
19002 if (cuddTestInteract(table,xindex,yindex)) {
19003 isolated = table->vars[xindex]->ref == 1;
19004 L += table->subtables[y].keys - isolated;
19005 }
19006 move = (Move *) cuddDynamicAllocNode(table);
19007 if (move == NULL) goto ddSymmSiftingUpOutOfMem;
19008 move->x = x;
19009 move->y = y;
19010 move->size = size;
19011 move->next = moves;
19012 moves = move;
19013 if ((double) size > (double) limitSize * table->maxGrowth)
19014 return(moves);
19015 if (size < limitSize) limitSize = size;
19016 } else { /* Group move */
19017 size = ddSymmGroupMove(table,x,y,&moves);
19018 if (size == 0) goto ddSymmSiftingUpOutOfMem;
19019 /* Update the lower bound. */
19020 z = moves->y;
19021 do {
19022 zindex = table->invperm[z];
19023 if (cuddTestInteract(table,zindex,yindex)) {
19024 isolated = table->vars[zindex]->ref == 1;
19025 L += table->subtables[z].keys - isolated;
19026 }
19027 z = table->subtables[z].next;
19028 } while (z != (int) moves->y);
19029 if ((double) size > (double) limitSize * table->maxGrowth)
19030 return(moves);
19031 if (size < limitSize) limitSize = size;
19032 }
19033 y = gxtop;
19034 x = cuddNextLow(table,y);
19035 }
19036 
19037 return(moves);
19038 
19039 ddSymmSiftingUpOutOfMem:
19040 while (moves != NULL) {
19041 move = moves->next;
19042 cuddDeallocMove(table, moves);
19043 moves = move;
19044 }
19045 return(MV_OOM);
19046 
19047 } /* end of ddSymmSiftingUp */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
static int ddSymmGroupMove(DdManager *table, int x, int y, Move **moves)
Definition: cuddInt.c:19204
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
DdSubtable * subtables
Definition: cuddInt.h:349
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
#define MV_OOM
Definition: cuddInt.c:17842
unsigned int keys
Definition: cuddInt.h:353
DdHalfWord x
Definition: cuddInt.h:470
int cuddSymmCheck(DdManager *table, int x, int y)
Definition: cuddInt.c:17912
DdHalfWord y
Definition: cuddInt.h:471
DdNode ** vars
Definition: cuddInt.h:373
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int cuddTestInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10917
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int size
Definition: cuddInt.h:473

◆ ddSymmSummary()

static void ddSymmSummary ( DdManager table,
int  lower,
int  upper,
int *  symvars,
int *  symgroups 
)
static

Function********************************************************************

Synopsis [Counts numbers of symmetric variables and symmetry groups.]

Description []

SideEffects [None]

Definition at line 19400 of file cuddInt.c.

19406 {
19407 int i,x,gbot;
19408 int TotalSymm = 0;
19409 int TotalSymmGroups = 0;
19410 
19411 for (i = lower; i <= upper; i++) {
19412 if (table->subtables[i].next != (unsigned) i) {
19413 TotalSymmGroups++;
19414 x = i;
19415 do {
19416 TotalSymm++;
19417 gbot = x;
19418 x = table->subtables[x].next;
19419 } while (x != i);
19420 #ifdef DD_DEBUG
19421 assert(table->subtables[gbot].next == (unsigned) i);
19422 #endif
19423 i = gbot;
19424 }
19425 }
19426 *symvars = TotalSymm;
19427 *symgroups = TotalSymmGroups;
19428 
19429 return;
19430 
19431 } /* end of ddSymmSummary */
#define assert(ex)
Definition: util.h:141
DdSubtable * subtables
Definition: cuddInt.h:349
unsigned int next
Definition: cuddInt.h:317

◆ ddSymmUniqueCompare()

static int ddSymmUniqueCompare ( int *  ptrX,
int *  ptrY 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Comparison function used by qsort.]

Description [Comparison function used by qsort to order the variables according to the number of keys in the subtables. Returns the difference in number of keys between the two variables being compared.]

SideEffects [None]

Definition at line 18337 of file cuddInt.c.

18340 {
18341 #if 0
18342 if (entry[*ptrY] == entry[*ptrX]) {
18343 return((*ptrX) - (*ptrY));
18344 }
18345 #endif
18346 return(entry[*ptrY] - entry[*ptrX]);
18347 
18348 } /* end of ddSymmUniqueCompare */
static int * entry
Definition: cuddInt.c:8422

◆ ddTreeSiftingAux()

static int ddTreeSiftingAux ( DdManager table,
MtrNode treenode,
Cudd_ReorderingType  method 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Visits the group tree and reorders each group.]

Description [Recursively visits the group tree and reorders each group in postorder fashion. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 8597 of file cuddInt.c.

8601 {
8602  MtrNode *auxnode;
8603  int res;
8604  Cudd_AggregationType saveCheck;
8605 
8606 #ifdef DD_DEBUG
8607  Mtr_PrintGroups(treenode,1);
8608 #endif
8609 
8610  auxnode = treenode;
8611  while (auxnode != NULL) {
8612  if (auxnode->child != NULL) {
8613  if (!ddTreeSiftingAux(table, auxnode->child, method))
8614  return(0);
8615  saveCheck = table->groupcheck;
8616  table->groupcheck = CUDD_NO_CHECK;
8617  if (method != CUDD_REORDER_LAZY_SIFT)
8618  res = ddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT);
8619  else
8620  res = ddReorderChildren(table, auxnode, CUDD_REORDER_LAZY_SIFT);
8621  table->groupcheck = saveCheck;
8622 
8623  if (res == 0)
8624  return(0);
8625  } else if (auxnode->size > 1) {
8626  if (!ddReorderChildren(table, auxnode, method))
8627  return(0);
8628  }
8629  auxnode = auxnode->younger;
8630  }
8631 
8632  return(1);
8633 
8634 } /* end of ddTreeSiftingAux */
Cudd_AggregationType groupcheck
Definition: cuddInt.h:410
static int ddReorderChildren(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddInt.c:8689
Cudd_AggregationType
Definition: cudd.h:174
MtrHalfWord size
Definition: mtr.h:129
static int ddTreeSiftingAux(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddInt.c:8597
struct MtrNode * younger
Definition: mtr.h:134
Definition: mtr.h:126
void Mtr_PrintGroups(MtrNode *root, int silent)
Definition: mtr.c:773
struct MtrNode * child
Definition: mtr.h:132

◆ ddUndoMoves()

static Move * ddUndoMoves ( DdManager table,
Move moves 
)
static

Function********************************************************************

Synopsis [Given a set of moves, returns the DD heap to the order in effect before the moves.]

Description [Given a set of moves, returns the DD heap to the order in effect before the moves. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 13798 of file cuddInt.c.

13801 {
13802  Move *invmoves = NULL;
13803  Move *move;
13804  Move *invmove;
13805  int size;
13806 
13807  for (move = moves; move != NULL; move = move->next) {
13808  invmove = (Move *) cuddDynamicAllocNode(table);
13809  if (invmove == NULL) goto ddUndoMovesOutOfMem;
13810  invmove->x = move->x;
13811  invmove->y = move->y;
13812  invmove->next = invmoves;
13813  invmoves = invmove;
13814  if (move->flags == CUDD_SWAP_MOVE) {
13815  invmove->flags = CUDD_SWAP_MOVE;
13816  size = cuddSwapInPlace(table,(int)move->x,(int)move->y);
13817  if (!size) goto ddUndoMovesOutOfMem;
13818  } else if (move->flags == CUDD_LINEAR_TRANSFORM_MOVE) {
13820  size = cuddLinearInPlace(table,(int)move->x,(int)move->y);
13821  if (!size) goto ddUndoMovesOutOfMem;
13822  size = cuddSwapInPlace(table,(int)move->x,(int)move->y);
13823  if (!size) goto ddUndoMovesOutOfMem;
13824  } else { /* must be CUDD_INVERSE_TRANSFORM_MOVE */
13825 #ifdef DD_DEBUG
13826  (void) fprintf(table->err,"Unforseen event in ddUndoMoves!\n");
13827 #endif
13828  invmove->flags = CUDD_LINEAR_TRANSFORM_MOVE;
13829  size = cuddSwapInPlace(table,(int)move->x,(int)move->y);
13830  if (!size) goto ddUndoMovesOutOfMem;
13831  size = cuddLinearInPlace(table,(int)move->x,(int)move->y);
13832  if (!size) goto ddUndoMovesOutOfMem;
13833  }
13834  invmove->size = size;
13835  }
13836 
13837  return(invmoves);
13838 
13839  ddUndoMovesOutOfMem:
13840  while (invmoves != NULL) {
13841  move = invmoves->next;
13842  cuddDeallocMove(table, invmoves);
13843  invmoves = move;
13844  }
13845  return((Move *) CUDD_OUT_OF_MEM);
13846 
13847 } /* end of ddUndoMoves */
#define CUDD_OUT_OF_MEM
Definition: cudd.h:88
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
FILE * err
Definition: cuddInt.h:424
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
#define CUDD_SWAP_MOVE
Definition: cuddInt.c:28542
int cuddLinearInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:12874
#define CUDD_INVERSE_TRANSFORM_MOVE
Definition: cuddInt.c:28544
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
#define CUDD_LINEAR_TRANSFORM_MOVE
Definition: cuddInt.c:28543
int size
Definition: cuddInt.h:473

◆ ddUniqueCompare()

static int ddUniqueCompare ( int *  ptrX,
int *  ptrY 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Comparison function used by qsort.]

Description [Comparison function used by qsort to order the variables according to the number of keys in the subtables. Returns the difference in number of keys between the two variables being compared.]

SideEffects [None]

Definition at line 15644 of file cuddInt.c.

15647 {
15648 #if 0
15649  if (entry[*ptrY] == entry[*ptrX]) {
15650  return((*ptrX) - (*ptrY));
15651  }
15652 #endif
15653  return(entry[*ptrY] - entry[*ptrX]);
15654 
15655 } /* end of ddUniqueCompare */
static int * entry
Definition: cuddInt.c:8422

◆ ddUniqueCompareGroup()

static int ddUniqueCompareGroup ( int *  ptrX,
int *  ptrY 
)
static

Function********************************************************************

Synopsis [Comparison function used by qsort.]

Description [Comparison function used by qsort to order the variables according to the number of keys in the subtables. Returns the difference in number of keys between the two variables being compared.]

SideEffects [None]

Definition at line 8928 of file cuddInt.c.

8931 {
8932 #if 0
8933  if (entry[*ptrY] == entry[*ptrX]) {
8934  return((*ptrX) - (*ptrY));
8935  }
8936 #endif
8937  return(entry[*ptrY] - entry[*ptrX]);
8938 
8939 } /* end of ddUniqueCompareGroup */
static int * entry
Definition: cuddInt.c:8422

◆ ddUpdateInteract()

static void ddUpdateInteract ( DdManager table,
char *  support 
)
static

Function********************************************************************

Synopsis [Marks as interacting all pairs of variables that appear in support.]

Description [If support[i] == support[j] == 1, sets the (i,j) entry of the interaction matrix to 1.]

SideEffects [Clears support.]

SeeAlso []

Definition at line 11103 of file cuddInt.c.

11106 {
11107  int i,j;
11108  int n = table->size;
11109 
11110  for (i = 0; i < n-1; i++) {
11111  if (support[i] == 1) {
11112  support[i] = 0;
11113  for (j = i+1; j < n; j++) {
11114  if (support[j] == 1) {
11115  cuddSetInteract(table,i,j);
11116  }
11117  }
11118  }
11119  }
11120  support[n-1] = 0;
11121 
11122 } /* end of ddUpdateInteract */
int size
Definition: cuddInt.h:345
void cuddSetInteract(DdManager *table, int x, int y)
Definition: cuddInt.c:10882

◆ ddUpdateMtrTree()

static int ddUpdateMtrTree ( DdManager table,
MtrNode treenode,
int *  perm,
int *  invperm 
)
static

Function********************************************************************

Synopsis [Updates the BDD variable group tree before a shuffle.]

Description [Updates the BDD variable group tree before a shuffle. Returns 1 if successful; 0 otherwise.]

SideEffects [Changes the BDD variable group tree.]

SeeAlso []

Definition at line 16365 of file cuddInt.c.

16370 {
16371  unsigned int i, size;
16372  int index, level, minLevel, maxLevel, minIndex;
16373 
16374  if (treenode == NULL) return(1);
16375 
16376  minLevel = CUDD_MAXINDEX;
16377  maxLevel = 0;
16378  minIndex = -1;
16379  /* i : level */
16380  for (i = treenode->low; i < treenode->low + treenode->size; i++) {
16381  index = table->invperm[i];
16382  level = perm[index];
16383  if (level < minLevel) {
16384  minLevel = level;
16385  minIndex = index;
16386  }
16387  if (level > maxLevel)
16388  maxLevel = level;
16389  }
16390  size = maxLevel - minLevel + 1;
16391  if (minIndex == -1) return(0);
16392  if (size == treenode->size) {
16393  treenode->low = minLevel;
16394  treenode->index = minIndex;
16395  } else {
16396  return(0);
16397  }
16398 
16399  if (treenode->child != NULL) {
16400  if (!ddUpdateMtrTree(table, treenode->child, perm, invperm))
16401  return(0);
16402  }
16403  if (treenode->younger != NULL) {
16404  if (!ddUpdateMtrTree(table, treenode->younger, perm, invperm))
16405  return(0);
16406  }
16407  return(1);
16408 }
MtrHalfWord size
Definition: mtr.h:129
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord index
Definition: mtr.h:130
MtrHalfWord low
Definition: mtr.h:128
static int ddUpdateMtrTree(DdManager *table, MtrNode *treenode, int *perm, int *invperm)
Definition: cuddInt.c:16365
#define CUDD_MAXINDEX
Definition: cudd.h:102
int * invperm
Definition: cuddInt.h:371
struct MtrNode * child
Definition: mtr.h:132

◆ ddVarGroupCheck()

static int ddVarGroupCheck ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [Checks for grouping of x and y.]

Description [Checks for grouping of x and y. Returns 1 in case of grouping; 0 otherwise. This function is used for lazy sifting.]

SideEffects [None]

Definition at line 10329 of file cuddInt.c.

10333 {
10334  int xindex = table->invperm[x];
10335  int yindex = table->invperm[y];
10336 
10337  if (Cudd_bddIsVarToBeUngrouped(table, xindex)) return(0);
10338 
10339  if (Cudd_bddReadPairIndex(table, xindex) == yindex) {
10340  if (ddIsVarHandled(table, xindex) ||
10341  ddIsVarHandled(table, yindex)) {
10342  if (Cudd_bddIsVarToBeGrouped(table, xindex) ||
10343  Cudd_bddIsVarToBeGrouped(table, yindex) ) {
10344  if (table->keys - table->isolated <= originalSize) {
10345  return(1);
10346  }
10347  }
10348  }
10349  }
10350 
10351  return(0);
10352 
10353 } /* end of ddVarGroupCheck */
static unsigned int originalSize
Definition: cuddInt.c:8436
unsigned int keys
Definition: cuddInt.h:353
int Cudd_bddIsVarToBeGrouped(DdManager *dd, int index)
Definition: cuddInt.c:2067
int Cudd_bddReadPairIndex(DdManager *dd, int index)
Definition: cuddInt.c:2044
static int ddIsVarHandled(DdManager *dd, int index)
Definition: cuddInt.c:10417
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368
int Cudd_bddIsVarToBeUngrouped(DdManager *dd, int index)
Definition: cuddInt.c:2096

◆ ddWindow2()

static int ddWindow2 ( DdManager table,
int  low,
int  high 
)
static

CFile***********************************************************************

FileName [cuddWindow.c]

PackageName [cudd]

Synopsis [Functions for variable reordering by window permutation.]

Description [Internal procedures included in this module:

Static procedures included in this module:

]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart

Function********************************************************************

Synopsis [Reorders by applying a sliding window of width 2.]

Description [Reorders by applying a sliding window of width 2. Tries both permutations of the variables in a window that slides from low to high. Assumes that no dead nodes are present. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 24195 of file cuddInt.c.

24199 {
24200 
24201 int x;
24202 int res;
24203 int size;
24204 
24205 #ifdef DD_DEBUG
24206 assert(low >= 0 && high < table->size);
24207 #endif
24208 
24209 if (high-low < 1) return(0);
24210 
24211 res = table->keys - table->isolated;
24212 for (x = low; x < high; x++) {
24213 size = res;
24214 res = cuddSwapInPlace(table,x,x+1);
24215 if (res == 0) return(0);
24216 if (res >= size) { /* no improvement: undo permutation */
24217 res = cuddSwapInPlace(table,x,x+1);
24218 if (res == 0) return(0);
24219 }
24220 #ifdef DD_STATS
24221 if (res < size) {
24222 (void) fprintf(table->out,"-");
24223 } else {
24224 (void) fprintf(table->out,"=");
24225 }
24226 fflush(table->out);
24227 #endif
24228 }
24229 
24230 return(1);
24231 
24232 } /* end of ddWindow2 */
#define assert(ex)
Definition: util.h:141
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
int isolated
Definition: cuddInt.h:368

◆ ddWindow3()

static int ddWindow3 ( DdManager table,
int  low,
int  high 
)
static

Function********************************************************************

Synopsis [Reorders by applying a sliding window of width 3.]

Description [Reorders by applying a sliding window of width 3. Tries all possible permutations to the variables in a window that slides from low to high. Assumes that no dead nodes are present. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 24437 of file cuddInt.c.

24441 {
24442 
24443 int x;
24444 int res;
24445 
24446 #ifdef DD_DEBUG
24447 assert(low >= 0 && high < table->size);
24448 #endif
24449 
24450 if (high-low < 2) return(ddWindow2(table,low,high));
24451 
24452 for (x = low; x+1 < high; x++) {
24453 res = ddPermuteWindow3(table,x);
24454 if (res == 0) return(0);
24455 #ifdef DD_STATS
24456 if (res == ABC) {
24457 (void) fprintf(table->out,"=");
24458 } else {
24459 (void) fprintf(table->out,"-");
24460 }
24461 fflush(table->out);
24462 #endif
24463 }
24464 
24465 return(1);
24466 
24467 } /* end of ddWindow3 */
#define assert(ex)
Definition: util.h:141
static int ddWindow2(DdManager *table, int low, int high)
Definition: cuddInt.c:24195
#define ABC
FILE * out
Definition: cuddInt.h:423
static int ddPermuteWindow3(DdManager *table, int x)
Definition: cuddInt.c:24342

◆ ddWindow4()

static int ddWindow4 ( DdManager table,
int  low,
int  high 
)
static

Function********************************************************************

Synopsis [Reorders by applying a sliding window of width 4.]

Description [Reorders by applying a sliding window of width 4. Tries all possible permutations to the variables in a window that slides from low to high. Assumes that no dead nodes are present. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 24838 of file cuddInt.c.

24842 {
24843 
24844 int w;
24845 int res;
24846 
24847 #ifdef DD_DEBUG
24848 assert(low >= 0 && high < table->size);
24849 #endif
24850 
24851 if (high-low < 3) return(ddWindow3(table,low,high));
24852 
24853 for (w = low; w+2 < high; w++) {
24854 res = ddPermuteWindow4(table,w);
24855 if (res == 0) return(0);
24856 #ifdef DD_STATS
24857 if (res == ABCD) {
24858 (void) fprintf(table->out,"=");
24859 } else {
24860 (void) fprintf(table->out,"-");
24861 }
24862 fflush(table->out);
24863 #endif
24864 }
24865 
24866 return(1);
24867 
24868 } /* end of ddWindow4 */
#define assert(ex)
Definition: util.h:141
#define ABCD
FILE * out
Definition: cuddInt.h:423
static int ddWindow3(DdManager *table, int low, int high)
Definition: cuddInt.c:24437
static int ddPermuteWindow4(DdManager *table, int w)
Definition: cuddInt.c:24582

◆ ddWindowConv2()

static int ddWindowConv2 ( DdManager table,
int  low,
int  high 
)
static

Function********************************************************************

Synopsis [Reorders by repeatedly applying a sliding window of width 2.]

Description [Reorders by repeatedly applying a sliding window of width

  1. Tries both permutations of the variables in a window that slides from low to high. Assumes that no dead nodes are present. Uses an event-driven approach to determine convergence. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 24249 of file cuddInt.c.

24253 {
24254 int x;
24255 int res;
24256 int nwin;
24257 int newevent;
24258 int *events;
24259 int size;
24260 
24261 #ifdef DD_DEBUG
24262 assert(low >= 0 && high < table->size);
24263 #endif
24264 
24265 if (high-low < 1) return(ddWindowConv2(table,low,high));
24266 
24267 nwin = high-low;
24268 events = ALLOC(int,nwin);
24269 if (events == NULL) {
24270 table->errorCode = CUDD_MEMORY_OUT;
24271 return(0);
24272 }
24273 for (x=0; x<nwin; x++) {
24274 events[x] = 1;
24275 }
24276 
24277 res = table->keys - table->isolated;
24278 do {
24279 newevent = 0;
24280 for (x=0; x<nwin; x++) {
24281 if (events[x]) {
24282 size = res;
24283 res = cuddSwapInPlace(table,x+low,x+low+1);
24284 if (res == 0) {
24285 FREE(events);
24286 return(0);
24287 }
24288 if (res >= size) { /* no improvement: undo permutation */
24289 res = cuddSwapInPlace(table,x+low,x+low+1);
24290 if (res == 0) {
24291 FREE(events);
24292 return(0);
24293 }
24294 }
24295 if (res < size) {
24296 if (x < nwin-1) events[x+1] = 1;
24297 if (x > 0) events[x-1] = 1;
24298 newevent = 1;
24299 }
24300 events[x] = 0;
24301 #ifdef DD_STATS
24302 if (res < size) {
24303 (void) fprintf(table->out,"-");
24304 } else {
24305 (void) fprintf(table->out,"=");
24306 }
24307 fflush(table->out);
24308 #endif
24309 }
24310 }
24311 #ifdef DD_STATS
24312 if (newevent) {
24313 (void) fprintf(table->out,"|");
24314 fflush(table->out);
24315 }
24316 #endif
24317 } while (newevent);
24318 
24319 FREE(events);
24320 
24321 return(1);
24322 
24323 } /* end of ddWindowConv3 */
#define FREE(obj)
Definition: util.h:80
#define assert(ex)
Definition: util.h:141
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
unsigned int keys
Definition: cuddInt.h:353
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
int isolated
Definition: cuddInt.h:368
static int ddWindowConv2(DdManager *table, int low, int high)
Definition: cuddInt.c:24249
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ ddWindowConv3()

static int ddWindowConv3 ( DdManager table,
int  low,
int  high 
)
static

Function********************************************************************

Synopsis [Reorders by repeatedly applying a sliding window of width 3.]

Description [Reorders by repeatedly applying a sliding window of width

  1. Tries all possible permutations to the variables in a window that slides from low to high. Assumes that no dead nodes are present. Uses an event-driven approach to determine convergence. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 24484 of file cuddInt.c.

24488 {
24489 int x;
24490 int res;
24491 int nwin;
24492 int newevent;
24493 int *events;
24494 
24495 #ifdef DD_DEBUG
24496 assert(low >= 0 && high < table->size);
24497 #endif
24498 
24499 if (high-low < 2) return(ddWindowConv2(table,low,high));
24500 
24501 nwin = high-low-1;
24502 events = ALLOC(int,nwin);
24503 if (events == NULL) {
24504 table->errorCode = CUDD_MEMORY_OUT;
24505 return(0);
24506 }
24507 for (x=0; x<nwin; x++) {
24508 events[x] = 1;
24509 }
24510 
24511 do {
24512 newevent = 0;
24513 for (x=0; x<nwin; x++) {
24514 if (events[x]) {
24515 res = ddPermuteWindow3(table,x+low);
24516 switch (res) {
24517 case ABC:
24518 break;
24519 case BAC:
24520 if (x < nwin-1) events[x+1] = 1;
24521 if (x > 1) events[x-2] = 1;
24522 newevent = 1;
24523 break;
24524 case BCA:
24525 case CBA:
24526 case CAB:
24527 if (x < nwin-2) events[x+2] = 1;
24528 if (x < nwin-1) events[x+1] = 1;
24529 if (x > 0) events[x-1] = 1;
24530 if (x > 1) events[x-2] = 1;
24531 newevent = 1;
24532 break;
24533 case ACB:
24534 if (x < nwin-2) events[x+2] = 1;
24535 if (x > 0) events[x-1] = 1;
24536 newevent = 1;
24537 break;
24538 default:
24539 FREE(events);
24540 return(0);
24541 }
24542 events[x] = 0;
24543 #ifdef DD_STATS
24544 if (res == ABC) {
24545 (void) fprintf(table->out,"=");
24546 } else {
24547 (void) fprintf(table->out,"-");
24548 }
24549 fflush(table->out);
24550 #endif
24551 }
24552 }
24553 #ifdef DD_STATS
24554 if (newevent) {
24555 (void) fprintf(table->out,"|");
24556 fflush(table->out);
24557 }
24558 #endif
24559 } while (newevent);
24560 
24561 FREE(events);
24562 
24563 return(1);
24564 
24565 } /* end of ddWindowConv3 */
#define FREE(obj)
Definition: util.h:80
#define BCA
#define CAB
#define assert(ex)
Definition: util.h:141
#define ABC
#define CBA
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
#define ACB
#define BAC
static int ddWindowConv2(DdManager *table, int low, int high)
Definition: cuddInt.c:24249
static int ddPermuteWindow3(DdManager *table, int x)
Definition: cuddInt.c:24342
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ ddWindowConv4()

static int ddWindowConv4 ( DdManager table,
int  low,
int  high 
)
static

Function********************************************************************

Synopsis [Reorders by repeatedly applying a sliding window of width 4.]

Description [Reorders by repeatedly applying a sliding window of width

  1. Tries all possible permutations to the variables in a window that slides from low to high. Assumes that no dead nodes are present. Uses an event-driven approach to determine convergence. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 24885 of file cuddInt.c.

24889 {
24890 int x;
24891 int res;
24892 int nwin;
24893 int newevent;
24894 int *events;
24895 
24896 #ifdef DD_DEBUG
24897 assert(low >= 0 && high < table->size);
24898 #endif
24899 
24900 if (high-low < 3) return(ddWindowConv3(table,low,high));
24901 
24902 nwin = high-low-2;
24903 events = ALLOC(int,nwin);
24904 if (events == NULL) {
24905 table->errorCode = CUDD_MEMORY_OUT;
24906 return(0);
24907 }
24908 for (x=0; x<nwin; x++) {
24909 events[x] = 1;
24910 }
24911 
24912 do {
24913 newevent = 0;
24914 for (x=0; x<nwin; x++) {
24915 if (events[x]) {
24916 res = ddPermuteWindow4(table,x+low);
24917 switch (res) {
24918 case ABCD:
24919 break;
24920 case BACD:
24921 if (x < nwin-1) events[x+1] = 1;
24922 if (x > 2) events[x-3] = 1;
24923 newevent = 1;
24924 break;
24925 case BADC:
24926 if (x < nwin-3) events[x+3] = 1;
24927 if (x < nwin-1) events[x+1] = 1;
24928 if (x > 0) events[x-1] = 1;
24929 if (x > 2) events[x-3] = 1;
24930 newevent = 1;
24931 break;
24932 case ABDC:
24933 if (x < nwin-3) events[x+3] = 1;
24934 if (x > 0) events[x-1] = 1;
24935 newevent = 1;
24936 break;
24937 case ADBC:
24938 case ADCB:
24939 case ACDB:
24940 if (x < nwin-3) events[x+3] = 1;
24941 if (x < nwin-2) events[x+2] = 1;
24942 if (x > 0) events[x-1] = 1;
24943 if (x > 1) events[x-2] = 1;
24944 newevent = 1;
24945 break;
24946 case DACB:
24947 case DABC:
24948 case DBAC:
24949 case BDAC:
24950 case BDCA:
24951 case DBCA:
24952 case DCBA:
24953 case DCAB:
24954 case CDAB:
24955 case CDBA:
24956 case CBDA:
24957 case BCDA:
24958 case CADB:
24959 if (x < nwin-3) events[x+3] = 1;
24960 if (x < nwin-2) events[x+2] = 1;
24961 if (x < nwin-1) events[x+1] = 1;
24962 if (x > 0) events[x-1] = 1;
24963 if (x > 1) events[x-2] = 1;
24964 if (x > 2) events[x-3] = 1;
24965 newevent = 1;
24966 break;
24967 case BCAD:
24968 case CBAD:
24969 case CABD:
24970 if (x < nwin-2) events[x+2] = 1;
24971 if (x < nwin-1) events[x+1] = 1;
24972 if (x > 1) events[x-2] = 1;
24973 if (x > 2) events[x-3] = 1;
24974 newevent = 1;
24975 break;
24976 case ACBD:
24977 if (x < nwin-2) events[x+2] = 1;
24978 if (x > 1) events[x-2] = 1;
24979 newevent = 1;
24980 break;
24981 default:
24982 FREE(events);
24983 return(0);
24984 }
24985 events[x] = 0;
24986 #ifdef DD_STATS
24987 if (res == ABCD) {
24988 (void) fprintf(table->out,"=");
24989 } else {
24990 (void) fprintf(table->out,"-");
24991 }
24992 fflush(table->out);
24993 #endif
24994 }
24995 }
24996 #ifdef DD_STATS
24997 if (newevent) {
24998 (void) fprintf(table->out,"|");
24999 fflush(table->out);
25000 }
25001 #endif
25002 } while (newevent);
25003 
25004 FREE(events);
25005 
25006 return(1);
25007 
25008 } /* end of ddWindowConv4 */
#define BDCA
#define DCBA
#define ACBD
#define FREE(obj)
Definition: util.h:80
#define BDAC
#define CADB
#define DBAC
#define ADCB
#define assert(ex)
Definition: util.h:141
#define CBDA
#define DABC
#define BCDA
#define ABCD
#define ADBC
#define DCAB
#define DBCA
#define CABD
#define BACD
#define CDAB
#define BADC
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
#define DACB
static int ddWindowConv3(DdManager *table, int low, int high)
Definition: cuddInt.c:24484
#define BCAD
#define ACDB
#define ABDC
#define CBAD
#define CDBA
static int ddPermuteWindow4(DdManager *table, int w)
Definition: cuddInt.c:24582
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ debugFindParent()

static void debugFindParent ( DdManager table,
DdNode node 
)
static

CFile***********************************************************************

FileName [cuddCheck.c]

PackageName [cudd]

Synopsis [Functions to check consistency of data structures.]

Description [External procedures included in this module:

Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart

Function********************************************************************

Synopsis [Searches the subtables above node for its parents.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 5929 of file cuddInt.c.

5932 {
5933  int i,j;
5934  int slots;
5935  DdNodePtr *nodelist;
5936  DdNode *f;
5937 
5938  for (i = 0; i < cuddI(table,node->index); i++) {
5939  nodelist = table->subtables[i].nodelist;
5940  slots = table->subtables[i].slots;
5941 
5942  for (j=0;j<slots;j++) {
5943  f = nodelist[j];
5944  while (f != NULL) {
5945  if (cuddT(f) == node || Cudd_Regular(cuddE(f)) == node) {
5946 #if SIZEOF_VOID_P == 8
5947  (void) fprintf(table->out,"parent is at 0x%lx, id = %u, ref = %u, then = 0x%lx, else = 0x%lx\n",
5948  (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f));
5949 #else
5950  (void) fprintf(table->out,"parent is at 0x%x, id = %hu, ref = %hu, then = 0x%x, else = 0x%x\n",
5951  (ptruint)f,f->index,f->ref,(ptruint)cuddT(f),(ptruint)cuddE(f));
5952 #endif
5953  }
5954  f = f->next;
5955  }
5956  }
5957  }
5958 
5959 } /* end of debugFindParent */
DdHalfWord ref
Definition: cudd.h:266
Definition: cudd.h:264
#define Cudd_Regular(node)
Definition: cudd.h:373
DdSubtable * subtables
Definition: cuddInt.h:349
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:267
DdNode ** nodelist
Definition: cuddInt.h:311
#define cuddT(node)
Definition: cuddInt.h:609
#define cuddI(dd, index)
Definition: cuddInt.h:659
unsigned int ptruint
Definition: cuddInt.h:250
DdHalfWord index
Definition: cudd.h:265
unsigned int slots
Definition: cuddInt.h:313
#define cuddE(node)
Definition: cuddInt.h:625

◆ dp2()

static int dp2 ( DdManager dd,
DdNode f,
st_table t 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Performs the recursive step of cuddP.]

Description [Performs the recursive step of cuddP. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 23106 of file cuddInt.c.

23110 {
23111 DdNode *g, *n, *N;
23112 int T,E;
23113 
23114 if (f == NULL) {
23115 return(0);
23116 }
23117 g = Cudd_Regular(f);
23118 if (cuddIsConstant(g)) {
23119 #if SIZEOF_VOID_P == 8
23120 (void) fprintf(dd->out,"ID = %c0x%lx\tvalue = %-9g\n", bang(f),
23121 (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g));
23122 #else
23123 (void) fprintf(dd->out,"ID = %c0x%x\tvalue = %-9g\n", bang(f),
23124 (ptruint) g / (ptruint) sizeof(DdNode),cuddV(g));
23125 #endif
23126 return(1);
23127 }
23128 if (st_is_member(t,(char *) g) == 1) {
23129 return(1);
23130 }
23131 if (st_add_direct(t,(char *) g,NULL) == ST_OUT_OF_MEM)
23132 return(0);
23133 #ifdef DD_STATS
23134 #if SIZEOF_VOID_P == 8
23135 (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %d\tr = %d\t", bang(f),
23136 (ptruint) g / (ptruint) sizeof(DdNode), g->index, g->ref);
23137 #else
23138 (void) fprintf(dd->out,"ID = %c0x%x\tindex = %d\tr = %d\t", bang(f),
23139 (ptruint) g / (ptruint) sizeof(DdNode),g->index,g->ref);
23140 #endif
23141 #else
23142 #if SIZEOF_VOID_P == 8
23143 (void) fprintf(dd->out,"ID = %c0x%lx\tindex = %u\t", bang(f),
23144 (ptruint) g / (ptruint) sizeof(DdNode),g->index);
23145 #else
23146 (void) fprintf(dd->out,"ID = %c0x%x\tindex = %hu\t", bang(f),
23147 (ptruint) g / (ptruint) sizeof(DdNode),g->index);
23148 #endif
23149 #endif
23150 n = cuddT(g);
23151 if (cuddIsConstant(n)) {
23152 (void) fprintf(dd->out,"T = %-9g\t",cuddV(n));
23153 T = 1;
23154 } else {
23155 #if SIZEOF_VOID_P == 8
23156 (void) fprintf(dd->out,"T = 0x%lx\t",(ptruint) n / (ptruint) sizeof(DdNode));
23157 #else
23158 (void) fprintf(dd->out,"T = 0x%x\t",(ptruint) n / (ptruint) sizeof(DdNode));
23159 #endif
23160 T = 0;
23161 }
23162 
23163 n = cuddE(g);
23164 N = Cudd_Regular(n);
23165 if (cuddIsConstant(N)) {
23166 (void) fprintf(dd->out,"E = %c%-9g\n",bang(n),cuddV(N));
23167 E = 1;
23168 } else {
23169 #if SIZEOF_VOID_P == 8
23170 (void) fprintf(dd->out,"E = %c0x%lx\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode));
23171 #else
23172 (void) fprintf(dd->out,"E = %c0x%x\n", bang(n), (ptruint) N/(ptruint) sizeof(DdNode));
23173 #endif
23174 E = 0;
23175 }
23176 if (E == 0) {
23177 if (dp2(dd,N,t) == 0)
23178 return(0);
23179 }
23180 if (T == 0) {
23181 if (dp2(dd,cuddT(g),t) == 0)
23182 return(0);
23183 }
23184 return(1);
23185 
23186 } /* end of dp2 */
DdHalfWord ref
Definition: cudd.h:266
Definition: cudd.h:264
#define Cudd_Regular(node)
Definition: cudd.h:373
struct DdNode DdNode
Definition: cudd.h:256
#define cuddV(node)
Definition: cuddInt.h:641
FILE * out
Definition: cuddInt.h:423
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
#define ST_OUT_OF_MEM
Definition: st.h:41
int st_add_direct(st_table *, void *, void *)
Definition: st.c:395
unsigned int ptruint
Definition: cuddInt.h:250
#define st_is_member(table, key)
Definition: st.h:107
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
#define bang(f)
Definition: cuddInt.c:22152
static int dp2(DdManager *dd, DdNode *f, st_table *t)
Definition: cuddInt.c:23106

◆ find_best()

static int find_best ( void  )
static

Function********************************************************************

Synopsis [Returns the index of the fittest individual.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 8080 of file cuddInt.c.

8081 {
8082  int i,small;
8083 
8084  small = 0;
8085  for (i = 1; i < popsize; i++) {
8086  if (STOREDD(i,numvars) < STOREDD(small,numvars)) {
8087  small = i;
8088  }
8089  }
8090  return(small);
8091 
8092 } /* end of find_best */
static int popsize
Definition: cuddInt.c:7451
static int numvars
Definition: cuddInt.c:7452
#define STOREDD(i, j)
Definition: cuddInt.c:7476

◆ fixVarTree()

static void fixVarTree ( MtrNode treenode,
int *  perm,
int  size 
)
static

CFile***********************************************************************

FileName [cuddAPI.c]

PackageName [cudd]

Synopsis [Application interface functions.]

Description [External procedures included in this module:

  • Cudd_addNewVar()
  • Cudd_addNewVarAtLevel()
  • Cudd_bddNewVar()
  • Cudd_bddNewVarAtLevel()
  • Cudd_addIthVar()
  • Cudd_bddIthVar()
  • Cudd_zddIthVar()
  • Cudd_zddVarsFromBddVars()
  • Cudd_addConst()
  • Cudd_IsNonConstant()
  • Cudd_ReadStartTime()
  • Cudd_ReadElapsedTime()
  • Cudd_SetStartTime()
  • Cudd_ResetStartTime()
  • Cudd_ReadTimeLimit()
  • Cudd_SetTimeLimit()
  • Cudd_UpdateTimeLimit()
  • Cudd_IncreaseTimeLimit()
  • Cudd_UnsetTimeLimit()
  • Cudd_TimeLimited()
  • Cudd_AutodynEnable()
  • Cudd_AutodynDisable()
  • Cudd_ReorderingStatus()
  • Cudd_AutodynEnableZdd()
  • Cudd_AutodynDisableZdd()
  • Cudd_ReorderingStatusZdd()
  • Cudd_zddRealignmentEnabled()
  • Cudd_zddRealignEnable()
  • Cudd_zddRealignDisable()
  • Cudd_bddRealignmentEnabled()
  • Cudd_bddRealignEnable()
  • Cudd_bddRealignDisable()
  • Cudd_ReadOne()
  • Cudd_ReadZddOne()
  • Cudd_ReadZero()
  • Cudd_ReadLogicZero()
  • Cudd_ReadPlusInfinity()
  • Cudd_ReadMinusInfinity()
  • Cudd_ReadBackground()
  • Cudd_SetBackground()
  • Cudd_ReadCacheSlots()
  • Cudd_ReadCacheUsedSlots()
  • Cudd_ReadCacheLookUps()
  • Cudd_ReadCacheHits()
  • Cudd_ReadMinHit()
  • Cudd_SetMinHit()
  • Cudd_ReadLooseUpTo()
  • Cudd_SetLooseUpTo()
  • Cudd_ReadMaxCache()
  • Cudd_ReadMaxCacheHard()
  • Cudd_SetMaxCacheHard()
  • Cudd_ReadSize()
  • Cudd_ReadSlots()
  • Cudd_ReadUsedSlots()
  • Cudd_ExpectedUsedSlots()
  • Cudd_ReadKeys()
  • Cudd_ReadDead()
  • Cudd_ReadMinDead()
  • Cudd_ReadReorderings()
  • Cudd_ReadMaxReorderings()
  • Cudd_SetMaxReorderings()
  • Cudd_ReadReorderingTime()
  • Cudd_ReadGarbageCollections()
  • Cudd_ReadGarbageCollectionTime()
  • Cudd_ReadNodesFreed()
  • Cudd_ReadNodesDropped()
  • Cudd_ReadUniqueLookUps()
  • Cudd_ReadUniqueLinks()
  • Cudd_ReadSiftMaxVar()
  • Cudd_SetSiftMaxVar()
  • Cudd_ReadMaxGrowth()
  • Cudd_SetMaxGrowth()
  • Cudd_ReadMaxGrowthAlternate()
  • Cudd_SetMaxGrowthAlternate()
  • Cudd_ReadReorderingCycle()
  • Cudd_SetReorderingCycle()
  • Cudd_ReadTree()
  • Cudd_SetTree()
  • Cudd_FreeTree()
  • Cudd_ReadZddTree()
  • Cudd_SetZddTree()
  • Cudd_FreeZddTree()
  • Cudd_NodeReadIndex()
  • Cudd_ReadPerm()
  • Cudd_ReadInvPerm()
  • Cudd_ReadVars()
  • Cudd_ReadEpsilon()
  • Cudd_SetEpsilon()
  • Cudd_ReadGroupCheck()
  • Cudd_SetGroupcheck()
  • Cudd_GarbageCollectionEnabled()
  • Cudd_EnableGarbageCollection()
  • Cudd_DisableGarbageCollection()
  • Cudd_DeadAreCounted()
  • Cudd_TurnOnCountDead()
  • Cudd_TurnOffCountDead()
  • Cudd_ReadRecomb()
  • Cudd_SetRecomb()
  • Cudd_ReadSymmviolation()
  • Cudd_SetSymmviolation()
  • Cudd_ReadArcviolation()
  • Cudd_SetArcviolation()
  • Cudd_ReadPopulationSize()
  • Cudd_SetPopulationSize()
  • Cudd_ReadNumberXovers()
  • Cudd_SetNumberXovers()
  • Cudd_ReadOrderRandomization()
  • Cudd_SetOrderRandomization()
  • Cudd_ReadMemoryInUse()
  • Cudd_PrintInfo()
  • Cudd_ReadPeakNodeCount()
  • Cudd_ReadPeakLiveNodeCount()
  • Cudd_ReadNodeCount()
  • Cudd_zddReadNodeCount()
  • Cudd_AddHook()
  • Cudd_RemoveHook()
  • Cudd_IsInHook()
  • Cudd_StdPreReordHook()
  • Cudd_StdPostReordHook()
  • Cudd_EnableReorderingReporting()
  • Cudd_DisableReorderingReporting()
  • Cudd_ReorderingReporting()
  • Cudd_PrintGroupedOrder()
  • Cudd_EnableOrderingMonitoring()
  • Cudd_DisableOrderingMonitoring()
  • Cudd_OrderingMonitoring()
  • Cudd_ReadErrorCode()
  • Cudd_ClearErrorCode()
  • Cudd_ReadStdout()
  • Cudd_SetStdout()
  • Cudd_ReadStderr()
  • Cudd_SetStderr()
  • Cudd_ReadNextReordering()
  • Cudd_SetNextReordering()
  • Cudd_ReadSwapSteps()
  • Cudd_ReadMaxLive()
  • Cudd_SetMaxLive()
  • Cudd_ReadMaxMemory()
  • Cudd_SetMaxMemory()
  • Cudd_bddBindVar()
  • Cudd_bddUnbindVar()
  • Cudd_bddVarIsBound()
  • Cudd_bddSetPiVar()
  • Cudd_bddSetPsVar()
  • Cudd_bddSetNsVar()
  • Cudd_bddIsPiVar()
  • Cudd_bddIsPsVar()
  • Cudd_bddIsNsVar()
  • Cudd_bddSetPairIndex()
  • Cudd_bddReadPairIndex()
  • Cudd_bddSetVarToBeGrouped()
  • Cudd_bddSetVarHardGroup()
  • Cudd_bddResetVarToBeGrouped()
  • Cudd_bddIsVarToBeGrouped()
  • Cudd_bddSetVarToBeUngrouped()
  • Cudd_bddIsVarToBeUngrouped()
  • Cudd_bddIsVarHardGroup()

Static procedures included in this module:

]

SeeAlso []

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart

Function********************************************************************

Synopsis [Fixes a variable group tree.]

Description []

SideEffects [Changes the variable group tree.]

SeeAlso []

Definition at line 2126 of file cuddInt.c.

2130 {
2131  treenode->index = treenode->low;
2132  treenode->low = ((int) treenode->index < size) ?
2133  perm[treenode->index] : treenode->index;
2134  if (treenode->child != NULL)
2135  fixVarTree(treenode->child, perm, size);
2136  if (treenode->younger != NULL)
2137  fixVarTree(treenode->younger, perm, size);
2138  return;
2139 
2140 } /* end of fixVarTree */
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord index
Definition: mtr.h:130
static void fixVarTree(MtrNode *treenode, int *perm, int size)
Definition: cuddInt.c:2126
MtrHalfWord low
Definition: mtr.h:128
struct MtrNode * child
Definition: mtr.h:132

◆ freeMatrix()

static void freeMatrix ( DdHalfWord **  matrix)
static

Function********************************************************************

Synopsis [Frees a two-dimensional matrix allocated by getMatrix.]

Description []

SideEffects [None]

SeeAlso [getMatrix]

Definition at line 6807 of file cuddInt.c.

6809 {
6810  FREE(matrix[0]);
6811  FREE(matrix);
6812  return;
6813 
6814 } /* end of freeMatrix */
#define FREE(obj)
Definition: util.h:80

◆ freePathPair()

static enum st_retval freePathPair ( char *  key,
char *  value,
char *  arg 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Frees the entries of the visited symbol table.]

Description [Frees the entries of the visited symbol table. Returns ST_CONTINUE.]

SideEffects [None]

Definition at line 17213 of file cuddInt.c.

17217  {
17218  cuddPathPair *pair;
17219 
17220  pair = (cuddPathPair *) value;
17221  FREE(pair);
17222  return(ST_CONTINUE);
17223 
17224  } /* end of freePathPair */
#define FREE(obj)
Definition: util.h:80
Definition: st.h:78

◆ getCube()

static DdNode * getCube ( DdManager manager,
st_table visited,
DdNode f,
int  cost 
)
static

Function********************************************************************

Synopsis [Build a BDD for a largest cube of f.]

Description [Build a BDD for a largest cube of f. Given the minimum length from the root, and the minimum lengths for each node (in visited), apply triangulation at each node. Of the two children of each node on a shortest path, at least one is on a shortest path. In case of ties the procedure chooses the THEN children. Returns a pointer to the cube BDD representing the path if successful; NULL otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 17435 of file cuddInt.c.

17440  {
17441  DdNode *sol, *tmp;
17442  DdNode *my_dd, *T, *E;
17443  cuddPathPair *T_pair, *E_pair;
17444  int Tcost, Ecost;
17445  int complement;
17446 
17447  my_dd = Cudd_Regular(f);
17448  complement = Cudd_IsComplement(f);
17449 
17450  sol = one;
17451  cuddRef(sol);
17452 
17453  while (!cuddIsConstant(my_dd)) {
17454  Tcost = cost - 1;
17455  Ecost = cost - 1;
17456 
17457  T = cuddT(my_dd);
17458  E = cuddE(my_dd);
17459 
17460  if (complement) {T = Cudd_Not(T); E = Cudd_Not(E);}
17461 
17462  if (!st_lookup(visited, Cudd_Regular(T), &T_pair)) return(NULL);
17463  if ((Cudd_IsComplement(T) && T_pair->neg == Tcost) ||
17464  (!Cudd_IsComplement(T) && T_pair->pos == Tcost)) {
17465  tmp = cuddBddAndRecur(manager,manager->vars[my_dd->index],sol);
17466  if (tmp == NULL) {
17467  Cudd_RecursiveDeref(manager,sol);
17468  return(NULL);
17469  }
17470  cuddRef(tmp);
17471  Cudd_RecursiveDeref(manager,sol);
17472  sol = tmp;
17473 
17474  complement = Cudd_IsComplement(T);
17475  my_dd = Cudd_Regular(T);
17476  cost = Tcost;
17477  continue;
17478  }
17479  if (!st_lookup(visited, Cudd_Regular(E), &E_pair)) return(NULL);
17480  if ((Cudd_IsComplement(E) && E_pair->neg == Ecost) ||
17481  (!Cudd_IsComplement(E) && E_pair->pos == Ecost)) {
17482  tmp = cuddBddAndRecur(manager,Cudd_Not(manager->vars[my_dd->index]),sol);
17483  if (tmp == NULL) {
17484  Cudd_RecursiveDeref(manager,sol);
17485  return(NULL);
17486  }
17487  cuddRef(tmp);
17488  Cudd_RecursiveDeref(manager,sol);
17489  sol = tmp;
17490  complement = Cudd_IsComplement(E);
17491  my_dd = Cudd_Regular(E);
17492  cost = Ecost;
17493  continue;
17494  }
17495  (void) fprintf(manager->err,"We shouldn't be here!\n");
17496  manager->errorCode = CUDD_INTERNAL_ERROR;
17497  return(NULL);
17498  }
17499 
17500  cuddDeref(sol);
17501  return(sol);
17502 
17503  } /* end of getCube */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
int st_lookup(st_table *, void *, void *)
Definition: st.c:271
Definition: cudd.h:264
#define Cudd_Not(node)
Definition: cudd.h:343
static DdNode * one
Definition: cuddInt.c:16562
#define Cudd_Regular(node)
Definition: cudd.h:373
FILE * err
Definition: cuddInt.h:424
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddInt.c:14027
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdHalfWord index
Definition: cudd.h:265
DdNode ** vars
Definition: cuddInt.h:373
#define cuddE(node)
Definition: cuddInt.h:625
DdNode * cuddBddAndRecur(DdManager *manager, DdNode *f, DdNode *g)
Definition: cuddInt.c:3633
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ getLargest()

static cuddPathPair getLargest ( DdNode root,
st_table visited 
)
static

Function********************************************************************

Synopsis [Finds the size of the largest cube(s) in a DD.]

Description [Finds the size of the largest cube(s) in a DD. This problem is translated into finding the shortest paths from a node when both THEN and ELSE arcs have unit lengths. Uses a local symbol table to store the lengths for each node. Only the lengths for the regular nodes are entered in the table, because those for the complement nodes are simply obtained by swapping the two lenghts. Returns a pair of lengths: the length of the shortest path to 1; and the length of the shortest path to 0. This is done so as to take complement arcs into account.]

SideEffects [none]

SeeAlso []

Definition at line 17347 of file cuddInt.c.

17350  {
17351  cuddPathPair *my_pair, res_pair, pair_T, pair_E;
17352  DdNode *my_root, *T, *E;
17353 
17354  my_root = Cudd_Regular(root);
17355 
17356  if (st_lookup(visited, my_root, &my_pair)) {
17357  if (Cudd_IsComplement(root)) {
17358  res_pair.pos = my_pair->neg;
17359  res_pair.neg = my_pair->pos;
17360  } else {
17361  res_pair.pos = my_pair->pos;
17362  res_pair.neg = my_pair->neg;
17363  }
17364  return(res_pair);
17365  }
17366 
17367  /* In the case of a BDD the following test is equivalent to
17368  ** testing whether the BDD is the constant 1. This formulation,
17369  ** however, works for ADDs as well, by assuming the usual
17370  ** dichotomy of 0 and != 0.
17371  */
17372  if (cuddIsConstant(my_root)) {
17373  if (my_root != zero) {
17374  res_pair.pos = 0;
17375  res_pair.neg = DD_BIGGY;
17376  } else {
17377  res_pair.pos = DD_BIGGY;
17378  res_pair.neg = 0;
17379  }
17380  } else {
17381  T = cuddT(my_root);
17382  E = cuddE(my_root);
17383 
17384  pair_T = getLargest(T, visited);
17385  pair_E = getLargest(E, visited);
17386  res_pair.pos = ddMin(pair_T.pos, pair_E.pos) + 1;
17387  res_pair.neg = ddMin(pair_T.neg, pair_E.neg) + 1;
17388  }
17389 
17390  my_pair = ALLOC(cuddPathPair, 1);
17391  if (my_pair == NULL) { /* simply do not cache this result */
17392  if (Cudd_IsComplement(root)) {
17393  int tmp = res_pair.pos;
17394  res_pair.pos = res_pair.neg;
17395  res_pair.neg = tmp;
17396  }
17397  return(res_pair);
17398  }
17399  my_pair->pos = res_pair.pos;
17400  my_pair->neg = res_pair.neg;
17401 
17402  /* Caching may fail without affecting correctness. */
17403  st_insert(visited, (char *)my_root, (char *)my_pair);
17404  if (Cudd_IsComplement(root)) {
17405  res_pair.pos = my_pair->neg;
17406  res_pair.neg = my_pair->pos;
17407  } else {
17408  res_pair.pos = my_pair->pos;
17409  res_pair.neg = my_pair->neg;
17410  }
17411  return(res_pair);
17412 
17413  } /* end of getLargest */
int st_lookup(st_table *, void *, void *)
Definition: st.c:271
Definition: cudd.h:264
#define Cudd_Regular(node)
Definition: cudd.h:373
int st_insert(st_table *, void *, void *)
Definition: st.c:343
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define ALLOC(type, num)
Definition: util.h:76
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#define DD_BIGGY
Definition: cuddInt.c:16539
static cuddPathPair getLargest(DdNode *root, st_table *visited)
Definition: cuddInt.c:17347
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562

◆ getLevelKeys()

static int getLevelKeys ( DdManager table,
int  l 
)
static

Function********************************************************************

Synopsis [Returns the number of nodes at one level of a unique table.]

Description [Returns the number of nodes at one level of a unique table. The projection function, if isolated, is not counted.]

SideEffects [None]

SeeAlso []

Definition at line 6830 of file cuddInt.c.

6833 {
6834  int isolated;
6835  int x; /* x is an index */
6836 
6837  x = table->invperm[l];
6838  isolated = table->vars[x]->ref == 1;
6839 
6840  return(table->subtables[l].keys - isolated);
6841 
6842 } /* end of getLevelKeys */
DdHalfWord ref
Definition: cudd.h:266
unsigned int keys
Definition: cuddInt.h:314
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode ** vars
Definition: cuddInt.h:373
int * invperm
Definition: cuddInt.h:371

◆ getMatrix()

static DdHalfWord ** getMatrix ( int  rows,
int  cols 
)
static

Function********************************************************************

Synopsis [Allocates a two-dimensional matrix of ints.]

Description [Allocates a two-dimensional matrix of ints. Returns the pointer to the matrix if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [freeMatrix]

Definition at line 6772 of file cuddInt.c.

6775 {
6776  DdHalfWord **matrix;
6777  int i;
6778 
6779  if (cols*rows == 0) return(NULL);
6780  matrix = ALLOC(DdHalfWord *, rows);
6781  if (matrix == NULL) return(NULL);
6782  matrix[0] = ALLOC(DdHalfWord, cols*rows);
6783  if (matrix[0] == NULL) {
6784  FREE(matrix);
6785  return(NULL);
6786  }
6787  for (i = 1; i < rows; i++) {
6788  matrix[i] = matrix[i-1] + cols;
6789  }
6790  return(matrix);
6791 
6792 } /* end of getMatrix */
unsigned short DdHalfWord
Definition: cudd.h:253
#define FREE(obj)
Definition: util.h:80
#define ALLOC(type, num)
Definition: util.h:76

◆ getMaxBinomial()

static int getMaxBinomial ( int  n)
static

CFile***********************************************************************

FileName [cuddExact.c]

PackageName [cudd]

Synopsis [Functions for exact variable reordering.]

Description [External procedures included in this file:

Internal procedures included in this module:

Static procedures included in this module:

]

Author [Cheng Hua, Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart

Function********************************************************************

Synopsis [Returns the maximum value of (n choose k) for a given n.]

Description [Computes the maximum value of (n choose k) for a given n. The maximum value occurs for k = n/2 when n is even, or k = (n-1)/2 when n is odd. The algorithm used in this procedure avoids intermediate overflow problems. It is based on the identity

  binomial(n,k) = n/k * binomial(n-1,k-1).

Returns the computed value if successful; -1 if out of range.]

SideEffects [None]

SeeAlso []

Definition at line 6684 of file cuddInt.c.

6686 {
6687  double i, j, result;
6688 
6689  if (n < 0 || n > 33) return(-1); /* error */
6690  if (n < 2) return(1);
6691 
6692  for (result = (double)((n+3)/2), i = result+1, j=2; i <= n; i++, j++) {
6693  result *= i;
6694  result /= j;
6695  }
6696 
6697  return((int)result);
6698 
6699 } /* end of getMaxBinomial */
static int result
Definition: cuddInt.c:7466

◆ getShortest()

static cuddPathPair getShortest ( DdNode root,
int *  cost,
int *  support,
st_table visited 
)
static

Function********************************************************************

Synopsis [Finds the length of the shortest path(s) in a DD.]

Description [Finds the length of the shortest path(s) in a DD. Uses a local symbol table to store the lengths for each node. Only the lengths for the regular nodes are entered in the table, because those for the complement nodes are simply obtained by swapping the two lenghts. Returns a pair of lengths: the length of the shortest path to 1; and the length of the shortest path to 0. This is done so as to take complement arcs into account.]

SideEffects [Accumulates the support of the DD in support.]

SeeAlso []

Definition at line 17246 of file cuddInt.c.

17251  {
17252  cuddPathPair *my_pair, res_pair, pair_T, pair_E;
17253  DdNode *my_root, *T, *E;
17254  int weight;
17255 
17256  my_root = Cudd_Regular(root);
17257 
17258  if (st_lookup(visited, my_root, &my_pair)) {
17259  if (Cudd_IsComplement(root)) {
17260  res_pair.pos = my_pair->neg;
17261  res_pair.neg = my_pair->pos;
17262  } else {
17263  res_pair.pos = my_pair->pos;
17264  res_pair.neg = my_pair->neg;
17265  }
17266  return(res_pair);
17267  }
17268 
17269  /* In the case of a BDD the following test is equivalent to
17270  ** testing whether the BDD is the constant 1. This formulation,
17271  ** however, works for ADDs as well, by assuming the usual
17272  ** dichotomy of 0 and != 0.
17273  */
17274  if (cuddIsConstant(my_root)) {
17275  if (my_root != zero) {
17276  res_pair.pos = 0;
17277  res_pair.neg = DD_BIGGY;
17278  } else {
17279  res_pair.pos = DD_BIGGY;
17280  res_pair.neg = 0;
17281  }
17282  } else {
17283  T = cuddT(my_root);
17284  E = cuddE(my_root);
17285 
17286  pair_T = getShortest(T, cost, support, visited);
17287  pair_E = getShortest(E, cost, support, visited);
17288  weight = WEIGHT(cost, my_root->index);
17289  res_pair.pos = ddMin(pair_T.pos+weight, pair_E.pos);
17290  res_pair.neg = ddMin(pair_T.neg+weight, pair_E.neg);
17291 
17292  /* Update support. */
17293  if (support != NULL) {
17294  support[my_root->index] = 1;
17295  }
17296  }
17297 
17298  my_pair = ALLOC(cuddPathPair, 1);
17299  if (my_pair == NULL) {
17300  if (Cudd_IsComplement(root)) {
17301  int tmp = res_pair.pos;
17302  res_pair.pos = res_pair.neg;
17303  res_pair.neg = tmp;
17304  }
17305  return(res_pair);
17306  }
17307  my_pair->pos = res_pair.pos;
17308  my_pair->neg = res_pair.neg;
17309 
17310  st_insert(visited, (char *)my_root, (char *)my_pair);
17311  if (Cudd_IsComplement(root)) {
17312  res_pair.pos = my_pair->neg;
17313  res_pair.neg = my_pair->pos;
17314  } else {
17315  res_pair.pos = my_pair->pos;
17316  res_pair.neg = my_pair->neg;
17317  }
17318  return(res_pair);
17319 
17320  } /* end of getShortest */
int st_lookup(st_table *, void *, void *)
Definition: st.c:271
Definition: cudd.h:264
#define Cudd_Regular(node)
Definition: cudd.h:373
int st_insert(st_table *, void *, void *)
Definition: st.c:343
#define Cudd_IsComplement(node)
Definition: cudd.h:401
#define ALLOC(type, num)
Definition: util.h:76
#define WEIGHT(weight, col)
Definition: cuddInt.c:16568
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define ddMin(x, y)
Definition: cuddInt.h:771
#define cuddT(node)
Definition: cuddInt.h:609
#define DD_BIGGY
Definition: cuddInt.c:16539
static cuddPathPair getShortest(DdNode *root, int *cost, int *support, st_table *visited)
Definition: cuddInt.c:17246
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
static DdNode * zero
Definition: cuddInt.c:16562

◆ initSymmInfo()

static DdHalfWord * initSymmInfo ( DdManager table,
int  lower,
int  upper 
)
static

Function********************************************************************

Synopsis [Gathers symmetry information.]

Description [Translates the symmetry information stored in the next field of each subtable from level to indices. This procedure is called immediately after symmetric sifting, so that the next fields are correct. By translating this informaton in terms of indices, we make it independent of subsequent reorderings. The format used is that of the next fields: a circular list where each variable points to the next variable in the same symmetry group. Only the entries between lower and upper are considered. The procedure returns a pointer to an array holding the symmetry information if successful; NULL otherwise.]

SideEffects [None]

SeeAlso [checkSymmInfo]

Definition at line 7293 of file cuddInt.c.

7297 {
7298  int level, index, next, nextindex;
7299  DdHalfWord *symmInfo;
7300 
7301  symmInfo = ALLOC(DdHalfWord, table->size);
7302  if (symmInfo == NULL) return(NULL);
7303 
7304  for (level = lower; level <= upper; level++) {
7305  index = table->invperm[level];
7306  next = table->subtables[level].next;
7307  nextindex = table->invperm[next];
7308  symmInfo[index] = nextindex;
7309  }
7310  return(symmInfo);
7311 
7312 } /* end of initSymmInfo */
unsigned short DdHalfWord
Definition: cudd.h:253
int size
Definition: cuddInt.h:345
DdSubtable * subtables
Definition: cuddInt.h:349
#define ALLOC(type, num)
Definition: util.h:76
unsigned int next
Definition: cuddInt.h:317
int * invperm
Definition: cuddInt.h:371

◆ largest()

static int largest ( void  )
static

Function********************************************************************

Synopsis [Finds the largest DD in the population.]

Description [Finds the largest DD in the population. If an order is repeated, it avoids choosing the copy that is in the computed table (it has repeat[i] > 1).]

SideEffects [None]

SeeAlso []

Definition at line 7968 of file cuddInt.c.

7969 {
7970  int i; /* loop var */
7971  int big; /* temporary holder to return result */
7972 
7973  big = 0;
7974  while (repeat[big] > 1) big++;
7975  for (i = big + 1; i < popsize; i++) {
7976  if (STOREDD(i,numvars) >= STOREDD(big,numvars) && repeat[i] <= 1) {
7977  big = i;
7978  }
7979  }
7980  return(big);
7981 
7982 } /* end of largest */
static int popsize
Definition: cuddInt.c:7451
static int numvars
Definition: cuddInt.c:7452
#define STOREDD(i, j)
Definition: cuddInt.c:7476
static int * repeat
Definition: cuddInt.c:7463

◆ make_random()

static int make_random ( DdManager table,
int  lower 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Generates the random sequences for the initial population.]

Description [Generates the random sequences for the initial population. The sequences are permutations of the indices between lower and upper in the current order.]

SideEffects [None]

SeeAlso []

Definition at line 7793 of file cuddInt.c.

7796 {
7797  int i,j; /* loop variables */
7798  int *used; /* is a number already in a permutation */
7799  int next; /* next random number without repetitions */
7800 
7801  used = ALLOC(int,numvars);
7802  if (used == NULL) {
7803  table->errorCode = CUDD_MEMORY_OUT;
7804  return(0);
7805  }
7806 #if 0
7807  #ifdef DD_STATS
7808  (void) fprintf(table->out,"Initial population before sifting\n");
7809  for (i = 0; i < 2; i++) {
7810  for (j = 0; j < numvars; j++) {
7811  (void) fprintf(table->out," %2d",STOREDD(i,j));
7812  }
7813  (void) fprintf(table->out,"\n");
7814  }
7815 #endif
7816 #endif
7817  for (i = 2; i < popsize; i++) {
7818  for (j = 0; j < numvars; j++) {
7819  used[j] = 0;
7820  }
7821  /* Generate a permutation of {0...numvars-1} and use it to
7822  ** permute the variables in the layesr from lower to upper.
7823  */
7824  for (j = 0; j < numvars; j++) {
7825  do {
7826  next = rand_int(numvars-1);
7827  } while (used[next] != 0);
7828  used[next] = 1;
7829  STOREDD(i,j) = table->invperm[next+lower];
7830  }
7831 #if 0
7832  #ifdef DD_STATS
7833  /* Print the order just generated. */
7834  for (j = 0; j < numvars; j++) {
7835  (void) fprintf(table->out," %2d",STOREDD(i,j));
7836  }
7837  (void) fprintf(table->out,"\n");
7838 #endif
7839 #endif
7840  }
7841  FREE(used);
7842  return(1);
7843 
7844 } /* end of make_random */
#define FREE(obj)
Definition: util.h:80
static int popsize
Definition: cuddInt.c:7451
static int numvars
Definition: cuddInt.c:7452
#define STOREDD(i, j)
Definition: cuddInt.c:7476
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
static int rand_int(int a)
Definition: cuddInt.c:7997
int * invperm
Definition: cuddInt.h:371
Cudd_ErrorType errorCode
Definition: cuddInt.h:425

◆ PMX()

static int PMX ( int  maxvar)
static

Function********************************************************************

Synopsis [Returns the average fitness of the population.]

Description []

SideEffects [None]

SeeAlso [] Function********************************************************************

Synopsis [Performs the crossover between two parents.]

Description [Performs the crossover between two randomly chosen parents, and creates two children, x1 and x2. Uses the Partially Matched Crossover operator.]

SideEffects [None]

SeeAlso []

Definition at line 8138 of file cuddInt.c.

8140 {
8141  int cut1,cut2; /* the two cut positions (random) */
8142  int mom,dad; /* the two randomly chosen parents */
8143  int *inv1; /* inverse permutations for repair algo */
8144  int *inv2;
8145  int i; /* loop vars */
8146  int u,v; /* aux vars */
8147 
8148  inv1 = ALLOC(int,maxvar);
8149  if (inv1 == NULL) {
8150  return(0);
8151  }
8152  inv2 = ALLOC(int,maxvar);
8153  if (inv2 == NULL) {
8154  FREE(inv1);
8155  return(0);
8156  }
8157 
8158  /* Choose two orders from the population using roulette wheel. */
8159  if (!roulette(&mom,&dad)) {
8160  FREE(inv1);
8161  FREE(inv2);
8162  return(0);
8163  }
8164 
8165  /* Choose two random cut positions. A cut in position i means that
8166  ** the cut immediately precedes position i. If cut1 < cut2, we
8167  ** exchange the middle of the two orderings; otherwise, we
8168  ** exchange the beginnings and the ends.
8169  */
8170  cut1 = rand_int(numvars-1);
8171  do {
8172  cut2 = rand_int(numvars-1);
8173  } while (cut1 == cut2);
8174 
8175 #if 0
8176  /* Print out the parents. */
8177  (void) fprintf(table->out,
8178  "Crossover of %d (mom) and %d (dad) between %d and %d\n",
8179  mom,dad,cut1,cut2);
8180  for (i = 0; i < numvars; i++) {
8181  if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
8182  (void) fprintf(table->out,"%2d ",STOREDD(mom,i));
8183  }
8184  (void) fprintf(table->out,"\n");
8185  for (i = 0; i < numvars; i++) {
8186  if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
8187  (void) fprintf(table->out,"%2d ",STOREDD(dad,i));
8188  }
8189  (void) fprintf(table->out,"\n");
8190 #endif
8191 
8192  /* Initialize the inverse permutations: -1 means yet undetermined. */
8193  for (i = 0; i < maxvar; i++) {
8194  inv1[i] = -1;
8195  inv2[i] = -1;
8196  }
8197 
8198  /* Copy the portions whithin the cuts. */
8199  for (i = cut1; i != cut2; i = (i == numvars-1) ? 0 : i+1) {
8200  STOREDD(popsize,i) = STOREDD(dad,i);
8201  inv1[STOREDD(popsize,i)] = i;
8202  STOREDD(popsize+1,i) = STOREDD(mom,i);
8203  inv2[STOREDD(popsize+1,i)] = i;
8204  }
8205 
8206  /* Now apply the repair algorithm outside the cuts. */
8207  for (i = cut2; i != cut1; i = (i == numvars-1 ) ? 0 : i+1) {
8208  v = i;
8209  do {
8210  u = STOREDD(mom,v);
8211  v = inv1[u];
8212  } while (v != -1);
8213  STOREDD(popsize,i) = u;
8214  inv1[u] = i;
8215  v = i;
8216  do {
8217  u = STOREDD(dad,v);
8218  v = inv2[u];
8219  } while (v != -1);
8220  STOREDD(popsize+1,i) = u;
8221  inv2[u] = i;
8222  }
8223 
8224 #if 0
8225  /* Print the results of crossover. */
8226  for (i = 0; i < numvars; i++) {
8227  if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
8228  (void) fprintf(table->out,"%2d ",STOREDD(popsize,i));
8229  }
8230  (void) fprintf(table->out,"\n");
8231  for (i = 0; i < numvars; i++) {
8232  if (i == cut1 || i == cut2) (void) fprintf(table->out,"|");
8233  (void) fprintf(table->out,"%2d ",STOREDD(popsize+1,i));
8234  }
8235  (void) fprintf(table->out,"\n");
8236 #endif
8237 
8238  FREE(inv1);
8239  FREE(inv2);
8240  return(1);
8241 
8242 } /* end of PMX */
#define FREE(obj)
Definition: util.h:80
static int popsize
Definition: cuddInt.c:7451
static int numvars
Definition: cuddInt.c:7452
#define STOREDD(i, j)
Definition: cuddInt.c:7476
#define ALLOC(type, num)
Definition: util.h:76
static int roulette(int *p1, int *p2)
Definition: cuddInt.c:8258
static int rand_int(int a)
Definition: cuddInt.c:7997

◆ pushDown()

static void pushDown ( DdHalfWord order,
int  j,
int  level 
)
static

Function********************************************************************

Synopsis [Pushes a variable in the order down to position "level."]

Description []

SideEffects [None]

SeeAlso []

Definition at line 7255 of file cuddInt.c.

7259 {
7260  int i;
7261  DdHalfWord tmp;
7262 
7263  tmp = order[j];
7264  for (i = j; i < level; i++) {
7265  order[i] = order[i+1];
7266  }
7267  order[level] = tmp;
7268  return;
7269 
7270 } /* end of pushDown */
unsigned short DdHalfWord
Definition: cudd.h:253

◆ rand_int()

static int rand_int ( int  a)
static

Function********************************************************************

Synopsis [Generates a random number between 0 and the integer a.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 7997 of file cuddInt.c.

7999 {
8000  return(Cudd_Random() % (a+1));
8001 
8002 } /* end of rand_int */
long Cudd_Random(void)
Definition: cuddInt.c:22881

◆ random_generator()

static double random_generator ( void  )
static

Function********************************************************************

Synopsis [Random number generator.]

Description [Returns a double precision value between 0.0 and 1.0.]

SideEffects [None]

SeeAlso []

Definition at line 942 of file cuddInt.c.

943 {
944  return((double)(Cudd_Random() / 2147483561.0));
945 
946 } /* end of random_generator */
long Cudd_Random(void)
Definition: cuddInt.c:22881

◆ restoreOrder()

static int restoreOrder ( DdManager table,
int *  array,
int  lower,
int  upper 
)
static

Function********************************************************************

Synopsis [Restores the variable order in array by a series of sifts up.]

Description [Restores the variable order in array by a series of sifts up. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 1395 of file cuddInt.c.

1400 {
1401  int i, x, y, size;
1402  int nvars = upper - lower + 1;
1403 
1404  for (i = 0; i < nvars; i++) {
1405  x = table->perm[array[i]];
1406 #ifdef DD_DEBUG
1407  assert(x >= lower && x <= upper);
1408 #endif
1409  y = cuddNextLow(table,x);
1410  while (y >= i + lower) {
1411  size = cuddSwapInPlace(table,y,x);
1412  if (size == 0) return(0);
1413  x = y;
1414  y = cuddNextLow(table,x);
1415  }
1416  }
1417 
1418  return(1);
1419 
1420 } /* end of restoreOrder */
#define assert(ex)
Definition: util.h:141
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
int * perm
Definition: cuddInt.h:369

◆ roulette()

static int roulette ( int *  p1,
int *  p2 
)
static

Function********************************************************************

Synopsis [Selects two parents with the roulette wheel method.]

Description [Selects two distinct parents with the roulette wheel method.]

SideEffects [The indices of the selected parents are returned as side effects.]

SeeAlso []

Definition at line 8258 of file cuddInt.c.

8261 {
8262  double *wheel;
8263  double spin;
8264  int i;
8265 
8266  wheel = ALLOC(double,popsize);
8267  if (wheel == NULL) {
8268  return(0);
8269  }
8270 
8271  /* The fitness of an individual is the reciprocal of its size. */
8272  wheel[0] = 1.0 / (double) STOREDD(0,numvars);
8273 
8274  for (i = 1; i < popsize; i++) {
8275  wheel[i] = wheel[i-1] + 1.0 / (double) STOREDD(i,numvars);
8276  }
8277 
8278  /* Get a random number between 0 and wheel[popsize-1] (that is,
8279  ** the sum of all fitness values. 2147483561 is the largest number
8280  ** returned by Cudd_Random.
8281  */
8282  spin = wheel[numvars-1] * (double) Cudd_Random() / 2147483561.0;
8283 
8284  /* Find the lucky element by scanning the wheel. */
8285  for (i = 0; i < popsize; i++) {
8286  if (spin <= wheel[i]) break;
8287  }
8288  *p1 = i;
8289 
8290  /* Repeat the process for the second parent, making sure it is
8291  ** distinct from the first.
8292  */
8293  do {
8294  spin = wheel[popsize-1] * (double) Cudd_Random() / 2147483561.0;
8295  for (i = 0; i < popsize; i++) {
8296  if (spin <= wheel[i]) break;
8297  }
8298  } while (i == *p1);
8299  *p2 = i;
8300 
8301  FREE(wheel);
8302  return(1);
8303 
8304 } /* end of roulette */
#define FREE(obj)
Definition: util.h:80
static int popsize
Definition: cuddInt.c:7451
static int numvars
Definition: cuddInt.c:7452
#define STOREDD(i, j)
Definition: cuddInt.c:7476
#define ALLOC(type, num)
Definition: util.h:76
long Cudd_Random(void)
Definition: cuddInt.c:22881

◆ sift_up()

static int sift_up ( DdManager table,
int  x,
int  x_low 
)
static

Function********************************************************************

Synopsis [Moves one variable up.]

Description [Takes a variable from position x and sifts it up to position x_low; x_low should be less than x. Returns 1 if successful; 0 otherwise]

SideEffects [None]

SeeAlso []

Definition at line 7861 of file cuddInt.c.

7865 {
7866  int y;
7867  int size;
7868 
7869  y = cuddNextLow(table,x);
7870  while (y >= x_low) {
7871  size = cuddSwapInPlace(table,y,x);
7872  if (size == 0) {
7873  return(0);
7874  }
7875  x = y;
7876  y = cuddNextLow(table,x);
7877  }
7878  return(1);
7879 
7880 } /* end of sift_up */
int cuddNextLow(DdManager *table, int x)
Definition: cuddInt.c:15059
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082

◆ siftBackwardProb()

static int siftBackwardProb ( DdManager table,
Move moves,
int  size,
double  temp 
)
static

Function********************************************************************

Synopsis [Returns the DD to the best position encountered during sifting if there was improvement.]

Description [Otherwise, "tosses a coin" to decide whether to keep the current configuration or return the DD to the original one. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 1301 of file cuddInt.c.

1306 {
1307  Move *move;
1308  int res;
1309  int best_size = size;
1310  double coin, threshold;
1311 
1312  /* Look for best size during the last sifting */
1313  for (move = moves; move != NULL; move = move->next) {
1314  if (move->size < best_size) {
1315  best_size = move->size;
1316  }
1317  }
1318 
1319  /* If best_size equals size, the last sifting did not produce any
1320  ** improvement. We now toss a coin to decide whether to retain
1321  ** this change or not.
1322  */
1323  if (best_size == size) {
1324  coin = random_generator();
1325 #ifdef DD_STATS
1326  tosses++;
1327 #endif
1328  threshold = exp(-((double)(table->keys - table->isolated - size))/temp);
1329  if (coin < threshold) {
1330 #ifdef DD_STATS
1331  acceptances++;
1332 #endif
1333  return(1);
1334  }
1335  }
1336 
1337  /* Either there was improvement, or we have decided not to
1338  ** accept the uphill move. Go to best position.
1339  */
1340  res = table->keys - table->isolated;
1341  for (move = moves; move != NULL; move = move->next) {
1342  if (res == best_size) return(1);
1343  res = cuddSwapInPlace(table,(int)move->x,(int)move->y);
1344  if (!res) return(0);
1345  }
1346 
1347  return(1);
1348 
1349 } /* end of sift_backward_prob */
Definition: cuddInt.h:469
int cuddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:15082
unsigned int keys
Definition: cuddInt.h:353
DdHalfWord x
Definition: cuddInt.h:470
DdHalfWord y
Definition: cuddInt.h:471
static double random_generator(void)
Definition: cuddInt.c:942
struct Move * next
Definition: cuddInt.h:474
int isolated
Definition: cuddInt.h:368
int size
Definition: cuddInt.h:473

◆ stopping_criterion()

static int stopping_criterion ( int  c1,
int  c2,
int  c3,
int  c4,
double  temp 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Checks termination condition.]

Description [If temperature is STOP_TEMP or there is no improvement then terminates. Returns 1 if the termination criterion is met; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 912 of file cuddInt.c.

918 {
919  if (STOP_TEMP < temp) {
920  return(0);
921  } else if ((c1 == c2) && (c1 == c3) && (c1 == c4)) {
922  return(1);
923  } else {
924  return(0);
925  }
926 
927 } /* end of stopping_criterion */
#define STOP_TEMP
Definition: cuddInt.c:685

◆ updateEntry()

static int updateEntry ( DdManager table,
DdHalfWord order,
int  level,
int  cost,
DdHalfWord **  orders,
int *  costs,
int  subsets,
char *  mask,
int  lower,
int  upper 
)
static

Function********************************************************************

Synopsis [Updates entry for a subset.]

Description [Updates entry for a subset. Finds the subset, if it exists. If the new order for the subset has lower cost, or if the subset did not exist, it stores the new order and cost. Returns the number of subsets currently in the table.]

SideEffects [None]

SeeAlso []

Definition at line 7201 of file cuddInt.c.

7212 {
7213  int i, j;
7214  int size = upper - lower + 1;
7215 
7216  /* Build a mask that says what variables are in this subset. */
7217  for (i = lower; i <= upper; i++)
7218  mask[table->invperm[i]] = 0;
7219  for (i = level; i < size; i++)
7220  mask[order[i]] = 1;
7221 
7222  /* Check each subset until a match is found or all subsets are examined. */
7223  for (i = 0; i < subsets; i++) {
7224  DdHalfWord *subset = orders[i];
7225  for (j = level; j < size; j++) {
7226  if (mask[subset[j]] == 0)
7227  break;
7228  }
7229  if (j == size) /* no mismatches: success */
7230  break;
7231  }
7232  if (i == subsets || cost < costs[i]) { /* add or replace */
7233  for (j = 0; j < size; j++)
7234  orders[i][j] = order[j];
7235  costs[i] = cost;
7236  subsets += (i == subsets);
7237  }
7238  return(subsets);
7239 
7240 } /* end of updateEntry */
unsigned short DdHalfWord
Definition: cudd.h:253
int * invperm
Definition: cuddInt.h:371

◆ updateUB()

static int updateUB ( DdManager table,
int  oldBound,
DdHalfWord bestOrder,
int  lower,
int  upper 
)
static

Function********************************************************************

Synopsis [Updates the upper bound and saves the best order seen so far.]

Description [Updates the upper bound and saves the best order seen so far. Returns the current value of the upper bound.]

SideEffects [None]

SeeAlso []

Definition at line 6979 of file cuddInt.c.

6985 {
6986  int i;
6987  int newBound = table->keys - table->isolated;
6988 
6989  if (newBound < oldBound) {
6990 #ifdef DD_STATS
6991  (void) fprintf(table->out,"New upper bound = %d\n", newBound);
6992  fflush(table->out);
6993 #endif
6994  for (i = lower; i <= upper; i++)
6995  bestOrder[i-lower] = (DdHalfWord) table->invperm[i];
6996  return(newBound);
6997  } else {
6998  return(oldBound);
6999  }
7000 
7001 } /* end of updateUB */
unsigned short DdHalfWord
Definition: cudd.h:253
unsigned int keys
Definition: cuddInt.h:353
FILE * out
Definition: cuddInt.h:423
int * invperm
Definition: cuddInt.h:371
int isolated
Definition: cuddInt.h:368

◆ zdd_group_move()

static int zdd_group_move ( DdManager table,
int  x,
int  y,
Move **  moves 
)
static

Function********************************************************************

Synopsis [Swaps two groups.]

Description [Swaps two groups. x is assumed to be the bottom variable of the first group. y is assumed to be the top variable of the second group. Updates the list of moves. Returns the number of keys in the table if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 33423 of file cuddInt.c.

33428 {
33429  Move *move;
33430  int size;
33431  int i, temp, gxtop, gxbot, gybot, yprev;
33432  int swapx, swapy;
33433 
33434 #ifdef DD_DEBUG
33435  assert(x < y); /* we assume that x < y */
33436 #endif
33437  /* Find top and bottom for the two groups. */
33438  gxtop = table->subtableZ[x].next;
33439  gxbot = x;
33440  gybot = table->subtableZ[y].next;
33441  while (table->subtableZ[gybot].next != (unsigned) y)
33442  gybot = table->subtableZ[gybot].next;
33443  yprev = gybot;
33444 
33445  while (x <= y) {
33446  while (y > gxtop) {
33447  /* Set correct symmetries. */
33448  temp = table->subtableZ[x].next;
33449  if (temp == x)
33450  temp = y;
33451  i = gxtop;
33452  for (;;) {
33453  if (table->subtableZ[i].next == (unsigned) x) {
33454  table->subtableZ[i].next = y;
33455  break;
33456  } else {
33457  i = table->subtableZ[i].next;
33458  }
33459  }
33460  if (table->subtableZ[y].next != (unsigned) y) {
33461  table->subtableZ[x].next = table->subtableZ[y].next;
33462  } else {
33463  table->subtableZ[x].next = x;
33464  }
33465 
33466  if (yprev != y) {
33467  table->subtableZ[yprev].next = x;
33468  } else {
33469  yprev = x;
33470  }
33471  table->subtableZ[y].next = temp;
33472 
33473  size = cuddZddSwapInPlace(table, x, y);
33474  if (size == 0)
33475  goto zdd_group_moveOutOfMem;
33476  swapx = x;
33477  swapy = y;
33478  y = x;
33479  x--;
33480  } /* while y > gxtop */
33481 
33482  /* Trying to find the next y. */
33483  if (table->subtableZ[y].next <= (unsigned) y) {
33484  gybot = y;
33485  } else {
33486  y = table->subtableZ[y].next;
33487  }
33488 
33489  yprev = gxtop;
33490  gxtop++;
33491  gxbot++;
33492  x = gxbot;
33493  } /* while x <= y, end of group movement */
33494  move = (Move *)cuddDynamicAllocNode(table);
33495  if (move == NULL)
33496  goto zdd_group_moveOutOfMem;
33497  move->x = swapx;
33498  move->y = swapy;
33499  move->size = table->keysZ;
33500  move->next = *moves;
33501  *moves = move;
33502 
33503  return(table->keysZ);
33504 
33505  zdd_group_moveOutOfMem:
33506  while (*moves != NULL) {
33507  move = (*moves)->next;
33508  cuddDeallocMove(table, *moves);
33509  *moves = move;
33510  }
33511  return(0);
33512 
33513 } /* end of zdd_group_move */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
int size
Definition: cuddInt.h:473
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zdd_group_move_backward()

static int zdd_group_move_backward ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [Undoes the swap of two groups.]

Description [Undoes the swap of two groups. x is assumed to be the bottom variable of the first group. y is assumed to be the top variable of the second group. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 33530 of file cuddInt.c.

33534 {
33535  int size;
33536  int i, temp, gxtop, gxbot, gybot, yprev;
33537 
33538 #ifdef DD_DEBUG
33539  assert(x < y); /* we assume that x < y */
33540 #endif
33541  /* Find top and bottom of the two groups. */
33542  gxtop = table->subtableZ[x].next;
33543  gxbot = x;
33544  gybot = table->subtableZ[y].next;
33545  while (table->subtableZ[gybot].next != (unsigned) y)
33546  gybot = table->subtableZ[gybot].next;
33547  yprev = gybot;
33548 
33549  while (x <= y) {
33550  while (y > gxtop) {
33551  /* Set correct symmetries. */
33552  temp = table->subtableZ[x].next;
33553  if (temp == x)
33554  temp = y;
33555  i = gxtop;
33556  for (;;) {
33557  if (table->subtableZ[i].next == (unsigned) x) {
33558  table->subtableZ[i].next = y;
33559  break;
33560  } else {
33561  i = table->subtableZ[i].next;
33562  }
33563  }
33564  if (table->subtableZ[y].next != (unsigned) y) {
33565  table->subtableZ[x].next = table->subtableZ[y].next;
33566  } else {
33567  table->subtableZ[x].next = x;
33568  }
33569 
33570  if (yprev != y) {
33571  table->subtableZ[yprev].next = x;
33572  } else {
33573  yprev = x;
33574  }
33575  table->subtableZ[y].next = temp;
33576 
33577  size = cuddZddSwapInPlace(table, x, y);
33578  if (size == 0)
33579  return(0);
33580  y = x;
33581  x--;
33582  } /* while y > gxtop */
33583 
33584  /* Trying to find the next y. */
33585  if (table->subtableZ[y].next <= (unsigned) y) {
33586  gybot = y;
33587  } else {
33588  y = table->subtableZ[y].next;
33589  }
33590 
33591  yprev = gxtop;
33592  gxtop++;
33593  gxbot++;
33594  x = gxbot;
33595  } /* while x <= y, end of group movement backward */
33596 
33597  return(size);
33598 
33599 } /* end of zdd_group_move_backward */
#define assert(ex)
Definition: util.h:141
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
unsigned int next
Definition: cuddInt.h:317
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zdd_subset0_aux()

static DdNode * zdd_subset0_aux ( DdManager zdd,
DdNode P,
DdNode zvar 
)
static

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddSubset0.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 31891 of file cuddInt.c.

31895 {
31896  int top_var, level;
31897  DdNode *res, *t, *e;
31898 
31899  statLine(zdd);
31900 
31901  /* Check cache. */
31902  res = cuddCacheLookup2Zdd(zdd, zdd_subset0_aux, P, zvar);
31903  if (res != NULL)
31904  return(res);
31905 
31906  if (cuddIsConstant(P)) {
31907  res = P;
31908  cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res);
31909  return(res);
31910  }
31911 
31912  top_var = zdd->permZ[P->index];
31913  level = zdd->permZ[zvar->index];
31914 
31915  if (top_var > level) {
31916  res = P;
31917  }
31918  else if (top_var == level) {
31919  res = cuddE(P);
31920  }
31921  else {
31922  t = zdd_subset0_aux(zdd, cuddT(P), zvar);
31923  if (t == NULL) return(NULL);
31924  cuddRef(t);
31925  e = zdd_subset0_aux(zdd, cuddE(P), zvar);
31926  if (e == NULL) {
31927  Cudd_RecursiveDerefZdd(zdd, t);
31928  return(NULL);
31929  }
31930  cuddRef(e);
31931  res = cuddZddGetNode(zdd, P->index, t, e);
31932  if (res == NULL) {
31933  Cudd_RecursiveDerefZdd(zdd, t);
31934  Cudd_RecursiveDerefZdd(zdd, e);
31935  return(NULL);
31936  }
31937  cuddDeref(t);
31938  cuddDeref(e);
31939  }
31940 
31941  cuddCacheInsert2(zdd, zdd_subset0_aux, P, zvar, res);
31942 
31943  return(res);
31944 
31945 } /* end of zdd_subset0_aux */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
static DdNode * zdd_subset0_aux(DdManager *zdd, DdNode *P, DdNode *zvar)
Definition: cuddInt.c:31891
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddInt.c:20408
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329

◆ zdd_subset1_aux()

static DdNode * zdd_subset1_aux ( DdManager zdd,
DdNode P,
DdNode zvar 
)
static

CFile***********************************************************************

FileName [cuddZddSetop.c]

PackageName [cudd]

Synopsis [Set operations on ZDDs.]

Description [External procedures included in this module:

  • Cudd_zddIte()
  • Cudd_zddUnion()
  • Cudd_zddIntersect()
  • Cudd_zddDiff()
  • Cudd_zddDiffConst()
  • Cudd_zddSubset1()
  • Cudd_zddSubset0()
  • Cudd_zddChange()

Internal procedures included in this module:

Static procedures included in this module:

]

SeeAlso []

Author [Hyong-Kyoon Shin, In-Ho Moon]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]AutomaticStart

Function********************************************************************

Synopsis [Performs the recursive step of Cudd_zddSubset1.]

Description []

SideEffects [None]

SeeAlso []

Definition at line 31822 of file cuddInt.c.

31826 {
31827  int top_var, level;
31828  DdNode *res, *t, *e;
31829  DdNode *empty;
31830 
31831  statLine(zdd);
31832  empty = DD_ZERO(zdd);
31833 
31834  /* Check cache. */
31835  res = cuddCacheLookup2Zdd(zdd, zdd_subset1_aux, P, zvar);
31836  if (res != NULL)
31837  return(res);
31838 
31839  if (cuddIsConstant(P)) {
31840  res = empty;
31841  cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res);
31842  return(res);
31843  }
31844 
31845  top_var = zdd->permZ[P->index];
31846  level = zdd->permZ[zvar->index];
31847 
31848  if (top_var > level) {
31849  res = empty;
31850  } else if (top_var == level) {
31851  res = cuddT(P);
31852  } else {
31853  t = zdd_subset1_aux(zdd, cuddT(P), zvar);
31854  if (t == NULL) return(NULL);
31855  cuddRef(t);
31856  e = zdd_subset1_aux(zdd, cuddE(P), zvar);
31857  if (e == NULL) {
31858  Cudd_RecursiveDerefZdd(zdd, t);
31859  return(NULL);
31860  }
31861  cuddRef(e);
31862  res = cuddZddGetNode(zdd, P->index, t, e);
31863  if (res == NULL) {
31864  Cudd_RecursiveDerefZdd(zdd, t);
31865  Cudd_RecursiveDerefZdd(zdd, e);
31866  return(NULL);
31867  }
31868  cuddDeref(t);
31869  cuddDeref(e);
31870  }
31871 
31872  cuddCacheInsert2(zdd, zdd_subset1_aux, P, zvar, res);
31873 
31874  return(res);
31875 
31876 } /* end of zdd_subset1_aux */
#define cuddRef(n)
Definition: cuddInt.h:557
#define cuddDeref(n)
Definition: cuddInt.h:577
Definition: cudd.h:264
static DdNode * empty
Definition: cuddInt.c:28567
int * permZ
Definition: cuddInt.h:370
#define statLine(dd)
Definition: cuddInt.h:990
DdNode * cuddCacheLookup2Zdd(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g)
Definition: cuddInt.c:4645
#define cuddIsConstant(node)
Definition: cuddInt.h:593
#define cuddT(node)
Definition: cuddInt.h:609
DdNode * cuddZddGetNode(DdManager *zdd, int id, DdNode *T, DdNode *E)
Definition: cuddInt.c:20408
DdHalfWord index
Definition: cudd.h:265
#define cuddE(node)
Definition: cuddInt.h:625
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddInt.c:14145
static DdNode * zdd_subset1_aux(DdManager *zdd, DdNode *P, DdNode *zvar)
Definition: cuddInt.c:31822
void cuddCacheInsert2(DdManager *table, DD_CTFP op, DdNode *f, DdNode *g, DdNode *data)
Definition: cuddInt.c:4329
#define DD_ZERO(dd)
Definition: cuddInt.h:880

◆ zddFindNodeHiLo()

static void zddFindNodeHiLo ( DdManager table,
MtrNode treenode,
int *  lower,
int *  upper 
)
static

Function********************************************************************

Synopsis [Finds the lower and upper bounds of the group represented by treenode.]

Description [Finds the lower and upper bounds of the group represented by treenode. The high and low fields of treenode are indices. From those we need to derive the current positions, and find maximum and minimum.]

SideEffects [The bounds are returned as side effects.]

SeeAlso []

Definition at line 26860 of file cuddInt.c.

26865 {
26866  int low;
26867  int high;
26868 
26869  /* Check whether no variables in this group already exist.
26870  ** If so, return immediately. The calling procedure will know from
26871  ** the values of upper that no reordering is needed.
26872  */
26873  if ((int) treenode->low >= table->sizeZ) {
26874  *lower = table->sizeZ;
26875  *upper = -1;
26876  return;
26877  }
26878 
26879  *lower = low = (unsigned int) table->permZ[treenode->index];
26880  high = (int) (low + treenode->size - 1);
26881 
26882  if (high >= table->sizeZ) {
26883  /* This is the case of a partially existing group. The aim is to
26884  ** reorder as many variables as safely possible. If the tree
26885  ** node is terminal, we just reorder the subset of the group
26886  ** that is currently in existence. If the group has
26887  ** subgroups, then we only reorder those subgroups that are
26888  ** fully instantiated. This way we avoid breaking up a group.
26889  */
26890  MtrNode *auxnode = treenode->child;
26891  if (auxnode == NULL) {
26892  *upper = (unsigned int) table->sizeZ - 1;
26893  } else {
26894  /* Search the subgroup that strands the table->sizeZ line.
26895  ** If the first group starts at 0 and goes past table->sizeZ
26896  ** upper will get -1, thus correctly signaling that no reordering
26897  ** should take place.
26898  */
26899  while (auxnode != NULL) {
26900  int thisLower = table->permZ[auxnode->low];
26901  int thisUpper = thisLower + auxnode->size - 1;
26902  if (thisUpper >= table->sizeZ && thisLower < table->sizeZ)
26903  *upper = (unsigned int) thisLower - 1;
26904  auxnode = auxnode->younger;
26905  }
26906  }
26907  } else {
26908  /* Normal case: All the variables of the group exist. */
26909  *upper = (unsigned int) high;
26910  }
26911 
26912 #ifdef DD_DEBUG
26913  /* Make sure that all variables in group are contiguous. */
26914  assert(treenode->size >= *upper - *lower + 1);
26915 #endif
26916 
26917  return;
26918 
26919 } /* end of zddFindNodeHiLo */
MtrHalfWord size
Definition: mtr.h:129
#define assert(ex)
Definition: util.h:141
int * permZ
Definition: cuddInt.h:370
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord index
Definition: mtr.h:130
MtrHalfWord low
Definition: mtr.h:128
Definition: mtr.h:126
int sizeZ
Definition: cuddInt.h:346
struct MtrNode * child
Definition: mtr.h:132

◆ zddFixTree()

static void zddFixTree ( DdManager table,
MtrNode treenode 
)
static

Function********************************************************************

Synopsis [Fixes the ZDD variable group tree after a shuffle.]

Description [Fixes the ZDD variable group tree after a shuffle. Assumes that the order of the variables in a terminal node has not been changed.]

SideEffects [Changes the ZDD variable group tree.]

SeeAlso []

Definition at line 31050 of file cuddInt.c.

31053 {
31054  if (treenode == NULL) return;
31055  treenode->low = ((int) treenode->index < table->sizeZ) ?
31056  table->permZ[treenode->index] : treenode->index;
31057  if (treenode->child != NULL) {
31058  zddFixTree(table, treenode->child);
31059  }
31060  if (treenode->younger != NULL)
31061  zddFixTree(table, treenode->younger);
31062  if (treenode->parent != NULL && treenode->low < treenode->parent->low) {
31063  treenode->parent->low = treenode->low;
31064  treenode->parent->index = treenode->index;
31065  }
31066  return;
31067 
31068 } /* end of zddFixTree */
static void zddFixTree(DdManager *table, MtrNode *treenode)
Definition: cuddInt.c:31050
int * permZ
Definition: cuddInt.h:370
struct MtrNode * parent
Definition: mtr.h:131
struct MtrNode * younger
Definition: mtr.h:134
MtrHalfWord index
Definition: mtr.h:130
MtrHalfWord low
Definition: mtr.h:128
int sizeZ
Definition: cuddInt.h:346
struct MtrNode * child
Definition: mtr.h:132

◆ zddGroupMove()

static int zddGroupMove ( DdManager table,
int  x,
int  y,
Move **  moves 
)
static

Function********************************************************************

Synopsis [Swaps two groups and records the move.]

Description [Swaps two groups and records the move. Returns the number of keys in the DD table in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 27408 of file cuddInt.c.

27413 {
27414  Move *move;
27415  int size;
27416  int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
27417  int swapx,swapy;
27418 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
27419  int initialSize,bestSize;
27420 #endif
27421 
27422 #ifdef DD_DEBUG
27423  /* We assume that x < y */
27424  assert(x < y);
27425 #endif
27426  /* Find top, bottom, and size for the two groups. */
27427  xbot = x;
27428  xtop = table->subtableZ[x].next;
27429  xsize = xbot - xtop + 1;
27430  ybot = y;
27431  while ((unsigned) ybot < table->subtableZ[ybot].next)
27432  ybot = table->subtableZ[ybot].next;
27433  ytop = y;
27434  ysize = ybot - ytop + 1;
27435 
27436 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
27437  initialSize = bestSize = table->keysZ;
27438 #endif
27439  /* Sift the variables of the second group up through the first group */
27440  for (i = 1; i <= ysize; i++) {
27441  for (j = 1; j <= xsize; j++) {
27442  size = cuddZddSwapInPlace(table,x,y);
27443  if (size == 0) goto zddGroupMoveOutOfMem;
27444 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
27445  if (size < bestSize)
27446  bestSize = size;
27447 #endif
27448  swapx = x; swapy = y;
27449  y = x;
27450  x = cuddZddNextLow(table,y);
27451  }
27452  y = ytop + i;
27453  x = cuddZddNextLow(table,y);
27454  }
27455 #if defined(DD_DEBUG) && defined(DD_VERBOSE)
27456  if ((bestSize < initialSize) && (bestSize < size))
27457  (void) fprintf(table->out,"Missed local minimum: initialSize:%d bestSize:%d finalSize:%d\n",initialSize,bestSize,size);
27458 #endif
27459 
27460  /* fix groups */
27461  y = xtop; /* ytop is now where xtop used to be */
27462  for (i = 0; i < ysize - 1; i++) {
27463  table->subtableZ[y].next = cuddZddNextHigh(table,y);
27464  y = cuddZddNextHigh(table,y);
27465  }
27466  table->subtableZ[y].next = xtop; /* y is bottom of its group, join */
27467  /* it to top of its group */
27468  x = cuddZddNextHigh(table,y);
27469  newxtop = x;
27470  for (i = 0; i < xsize - 1; i++) {
27471  table->subtableZ[x].next = cuddZddNextHigh(table,x);
27472  x = cuddZddNextHigh(table,x);
27473  }
27474  table->subtableZ[x].next = newxtop; /* x is bottom of its group, join */
27475  /* it to top of its group */
27476 #ifdef DD_DEBUG
27477  if (pr > 0) (void) fprintf(table->out,"zddGroupMove:\n");
27478 #endif
27479 
27480  /* Store group move */
27481  move = (Move *) cuddDynamicAllocNode(table);
27482  if (move == NULL) goto zddGroupMoveOutOfMem;
27483  move->x = swapx;
27484  move->y = swapy;
27485  move->flags = MTR_DEFAULT;
27486  move->size = table->keysZ;
27487  move->next = *moves;
27488  *moves = move;
27489 
27490  return(table->keysZ);
27491 
27492  zddGroupMoveOutOfMem:
27493  while (*moves != NULL) {
27494  move = (*moves)->next;
27495  cuddDeallocMove(table, *moves);
27496  *moves = move;
27497  }
27498  return(0);
27499 
27500 } /* end of zddGroupMove */
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:29814
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
#define MTR_DEFAULT
Definition: mtr.h:94
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddInt.c:29836
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
int size
Definition: cuddInt.h:473
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddGroupMoveBackward()

static int zddGroupMoveBackward ( DdManager table,
int  x,
int  y 
)
static

Function********************************************************************

Synopsis [Undoes the swap two groups.]

Description [Undoes the swap two groups. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 27514 of file cuddInt.c.

27518 {
27519  int size;
27520  int i,j,xtop,xbot,xsize,ytop,ybot,ysize,newxtop;
27521 
27522 
27523 #ifdef DD_DEBUG
27524  /* We assume that x < y */
27525  assert(x < y);
27526 #endif
27527 
27528  /* Find top, bottom, and size for the two groups. */
27529  xbot = x;
27530  xtop = table->subtableZ[x].next;
27531  xsize = xbot - xtop + 1;
27532  ybot = y;
27533  while ((unsigned) ybot < table->subtableZ[ybot].next)
27534  ybot = table->subtableZ[ybot].next;
27535  ytop = y;
27536  ysize = ybot - ytop + 1;
27537 
27538  /* Sift the variables of the second group up through the first group */
27539  for (i = 1; i <= ysize; i++) {
27540  for (j = 1; j <= xsize; j++) {
27541  size = cuddZddSwapInPlace(table,x,y);
27542  if (size == 0)
27543  return(0);
27544  y = x;
27545  x = cuddZddNextLow(table,y);
27546  }
27547  y = ytop + i;
27548  x = cuddZddNextLow(table,y);
27549  }
27550 
27551  /* fix groups */
27552  y = xtop;
27553  for (i = 0; i < ysize - 1; i++) {
27554  table->subtableZ[y].next = cuddZddNextHigh(table,y);
27555  y = cuddZddNextHigh(table,y);
27556  }
27557  table->subtableZ[y].next = xtop; /* y is bottom of its group, join */
27558  /* to its top */
27559  x = cuddZddNextHigh(table,y);
27560  newxtop = x;
27561  for (i = 0; i < xsize - 1; i++) {
27562  table->subtableZ[x].next = cuddZddNextHigh(table,x);
27563  x = cuddZddNextHigh(table,x);
27564  }
27565  table->subtableZ[x].next = newxtop; /* x is bottom of its group, join */
27566  /* to its top */
27567 #ifdef DD_DEBUG
27568  if (pr > 0) (void) fprintf(table->out,"zddGroupMoveBackward:\n");
27569 #endif
27570 
27571  return(1);
27572 
27573 } /* end of zddGroupMoveBackward */
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:29814
#define assert(ex)
Definition: util.h:141
FILE * out
Definition: cuddInt.h:423
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddInt.c:29836
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
unsigned int next
Definition: cuddInt.h:317
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddGroupSifting()

static int zddGroupSifting ( DdManager table,
int  lower,
int  upper 
)
static

Function********************************************************************

Synopsis [Sifts from treenode->low to treenode->high.]

Description [Sifts from treenode->low to treenode->high. If croupcheck == CUDD_GROUP_CHECK7, it checks for group creation at the end of the initial sifting. If a group is created, it is then sifted again. After sifting one variable, the group that contains it is dissolved. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 26963 of file cuddInt.c.

26967 {
26968  int *var;
26969  int i,j,x,xInit;
26970  int nvars;
26971  int classes;
26972  int result;
26973  int *sifted;
26974 #ifdef DD_STATS
26975  unsigned previousSize;
26976 #endif
26977  int xindex;
26978 
26979  nvars = table->sizeZ;
26980 
26981  /* Order variables to sift. */
26982  entry = NULL;
26983  sifted = NULL;
26984  var = ALLOC(int,nvars);
26985  if (var == NULL) {
26986  table->errorCode = CUDD_MEMORY_OUT;
26987  goto zddGroupSiftingOutOfMem;
26988  }
26989  entry = ALLOC(int,nvars);
26990  if (entry == NULL) {
26991  table->errorCode = CUDD_MEMORY_OUT;
26992  goto zddGroupSiftingOutOfMem;
26993  }
26994  sifted = ALLOC(int,nvars);
26995  if (sifted == NULL) {
26996  table->errorCode = CUDD_MEMORY_OUT;
26997  goto zddGroupSiftingOutOfMem;
26998  }
26999 
27000  /* Here we consider only one representative for each group. */
27001  for (i = 0, classes = 0; i < nvars; i++) {
27002  sifted[i] = 0;
27003  x = table->permZ[i];
27004  if ((unsigned) x >= table->subtableZ[x].next) {
27005  entry[i] = table->subtableZ[x].keys;
27006  var[classes] = i;
27007  classes++;
27008  }
27009  }
27010 
27011  qsort((void *)var,classes,sizeof(int),(DD_QSFP)zddUniqueCompareGroup);
27012 
27013  /* Now sift. */
27014  for (i = 0; i < ddMin(table->siftMaxVar,classes); i++) {
27015  if (zddTotalNumberSwapping >= table->siftMaxSwap)
27016  break;
27017  if (util_cpu_time() - table->startTime > table->timeLimit) {
27018  table->autoDynZ = 0; /* prevent further reordering */
27019  break;
27020  }
27021  xindex = var[i];
27022  if (sifted[xindex] == 1) /* variable already sifted as part of group */
27023  continue;
27024  x = table->permZ[xindex]; /* find current level of this variable */
27025  if (x < lower || x > upper)
27026  continue;
27027 #ifdef DD_STATS
27028  previousSize = table->keysZ;
27029 #endif
27030 #ifdef DD_DEBUG
27031  /* x is bottom of group */
27032  assert((unsigned) x >= table->subtableZ[x].next);
27033 #endif
27034  result = zddGroupSiftingAux(table,x,lower,upper);
27035  if (!result) goto zddGroupSiftingOutOfMem;
27036 
27037 #ifdef DD_STATS
27038  if (table->keysZ < previousSize) {
27039  (void) fprintf(table->out,"-");
27040  } else if (table->keysZ > previousSize) {
27041  (void) fprintf(table->out,"+");
27042  } else {
27043  (void) fprintf(table->out,"=");
27044  }
27045  fflush(table->out);
27046 #endif
27047 
27048  /* Mark variables in the group just sifted. */
27049  x = table->permZ[xindex];
27050  if ((unsigned) x != table->subtableZ[x].next) {
27051  xInit = x;
27052  do {
27053  j = table->invpermZ[x];
27054  sifted[j] = 1;
27055  x = table->subtableZ[x].next;
27056  } while (x != xInit);
27057  }
27058 
27059 #ifdef DD_DEBUG
27060  if (pr > 0) (void) fprintf(table->out,"zddGroupSifting:");
27061 #endif
27062  } /* for */
27063 
27064  FREE(sifted);
27065  FREE(var);
27066  FREE(entry);
27067 
27068  return(1);
27069 
27070  zddGroupSiftingOutOfMem:
27071  if (entry != NULL) FREE(entry);
27072  if (var != NULL) FREE(var);
27073  if (sifted != NULL) FREE(sifted);
27074 
27075  return(0);
27076 
27077 } /* end of zddGroupSifting */
unsigned int keys
Definition: cuddInt.h:314
#define FREE(obj)
Definition: util.h:80
int siftMaxSwap
Definition: cuddInt.h:396
int(* DD_QSFP)(const void *, const void *)
Definition: cudd.h:302
unsigned long startTime
Definition: cuddInt.h:426
int * invpermZ
Definition: cuddInt.h:372
#define assert(ex)
Definition: util.h:141
static int zddUniqueCompareGroup(int *ptrX, int *ptrY)
Definition: cuddInt.c:26935
static int zddGroupSiftingAux(DdManager *table, int x, int xLow, int xHigh)
Definition: cuddInt.c:27096
int * permZ
Definition: cuddInt.h:370
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
#define ddMin(x, y)
Definition: cuddInt.h:771
long util_cpu_time(void)
Definition: util.c:34
int zddTotalNumberSwapping
Definition: cuddInt.c:28565
int siftMaxVar
Definition: cuddInt.h:395
int sizeZ
Definition: cuddInt.h:346
static int result
Definition: cuddInt.c:7466
unsigned int next
Definition: cuddInt.h:317
int autoDynZ
Definition: cuddInt.h:401
static int * entry
Definition: cuddInt.c:8422
unsigned int keysZ
Definition: cuddInt.h:354
unsigned long timeLimit
Definition: cuddInt.h:427
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddGroupSiftingAux()

static int zddGroupSiftingAux ( DdManager table,
int  x,
int  xLow,
int  xHigh 
)
static

Function********************************************************************

Synopsis [Sifts one variable up and down until it has taken all positions. Checks for aggregation.]

Description [Sifts one variable up and down until it has taken all positions. Checks for aggregation. There may be at most two sweeps, even if the group grows. Assumes that x is either an isolated variable, or it is the bottom of a group. All groups may not have been found. The variable being moved is returned to the best position seen during sifting. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 27096 of file cuddInt.c.

27101 {
27102  Move *move;
27103  Move *moves; /* list of moves */
27104  int initialSize;
27105  int result;
27106 
27107 
27108 #ifdef DD_DEBUG
27109  if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingAux from %d to %d\n",xLow,xHigh);
27110  assert((unsigned) x >= table->subtableZ[x].next); /* x is bottom of group */
27111 #endif
27112 
27113  initialSize = table->keysZ;
27114  moves = NULL;
27115 
27116  if (x == xLow) { /* Sift down */
27117 #ifdef DD_DEBUG
27118  /* x must be a singleton */
27119  assert((unsigned) x == table->subtableZ[x].next);
27120 #endif
27121  if (x == xHigh) return(1); /* just one variable */
27122 
27123  if (!zddGroupSiftingDown(table,x,xHigh,&moves))
27124  goto zddGroupSiftingAuxOutOfMem;
27125  /* at this point x == xHigh, unless early term */
27126 
27127  /* move backward and stop at best position */
27128  result = zddGroupSiftingBackward(table,moves,initialSize);
27129 #ifdef DD_DEBUG
27130  assert(table->keysZ <= (unsigned) initialSize);
27131 #endif
27132  if (!result) goto zddGroupSiftingAuxOutOfMem;
27133 
27134  } else if (cuddZddNextHigh(table,x) > xHigh) { /* Sift up */
27135 #ifdef DD_DEBUG
27136  /* x is bottom of group */
27137  assert((unsigned) x >= table->subtableZ[x].next);
27138 #endif
27139  /* Find top of x's group */
27140  x = table->subtableZ[x].next;
27141 
27142  if (!zddGroupSiftingUp(table,x,xLow,&moves))
27143  goto zddGroupSiftingAuxOutOfMem;
27144  /* at this point x == xLow, unless early term */
27145 
27146  /* move backward and stop at best position */
27147  result = zddGroupSiftingBackward(table,moves,initialSize);
27148 #ifdef DD_DEBUG
27149  assert(table->keysZ <= (unsigned) initialSize);
27150 #endif
27151  if (!result) goto zddGroupSiftingAuxOutOfMem;
27152 
27153  } else if (x - xLow > xHigh - x) { /* must go down first: shorter */
27154  if (!zddGroupSiftingDown(table,x,xHigh,&moves))
27155  goto zddGroupSiftingAuxOutOfMem;
27156  /* at this point x == xHigh, unless early term */
27157 
27158  /* Find top of group */
27159  if (moves) {
27160  x = moves->y;
27161  }
27162  while ((unsigned) x < table->subtableZ[x].next)
27163  x = table->subtableZ[x].next;
27164  x = table->subtableZ[x].next;
27165 #ifdef DD_DEBUG
27166  /* x should be the top of a group */
27167  assert((unsigned) x <= table->subtableZ[x].next);
27168 #endif
27169 
27170  if (!zddGroupSiftingUp(table,x,xLow,&moves))
27171  goto zddGroupSiftingAuxOutOfMem;
27172 
27173  /* move backward and stop at best position */
27174  result = zddGroupSiftingBackward(table,moves,initialSize);
27175 #ifdef DD_DEBUG
27176  assert(table->keysZ <= (unsigned) initialSize);
27177 #endif
27178  if (!result) goto zddGroupSiftingAuxOutOfMem;
27179 
27180  } else { /* moving up first: shorter */
27181  /* Find top of x's group */
27182  x = table->subtableZ[x].next;
27183 
27184  if (!zddGroupSiftingUp(table,x,xLow,&moves))
27185  goto zddGroupSiftingAuxOutOfMem;
27186  /* at this point x == xHigh, unless early term */
27187 
27188  if (moves) {
27189  x = moves->x;
27190  }
27191  while ((unsigned) x < table->subtableZ[x].next)
27192  x = table->subtableZ[x].next;
27193 #ifdef DD_DEBUG
27194  /* x is bottom of a group */
27195  assert((unsigned) x >= table->subtableZ[x].next);
27196 #endif
27197 
27198  if (!zddGroupSiftingDown(table,x,xHigh,&moves))
27199  goto zddGroupSiftingAuxOutOfMem;
27200 
27201  /* move backward and stop at best position */
27202  result = zddGroupSiftingBackward(table,moves,initialSize);
27203 #ifdef DD_DEBUG
27204  assert(table->keysZ <= (unsigned) initialSize);
27205 #endif
27206  if (!result) goto zddGroupSiftingAuxOutOfMem;
27207  }
27208 
27209  while (moves != NULL) {
27210  move = moves->next;
27211  cuddDeallocMove(table, moves);
27212  moves = move;
27213  }
27214 
27215  return(1);
27216 
27217  zddGroupSiftingAuxOutOfMem:
27218  while (moves != NULL) {
27219  move = moves->next;
27220  cuddDeallocMove(table, moves);
27221  moves = move;
27222  }
27223 
27224  return(0);
27225 
27226 } /* end of zddGroupSiftingAux */
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:29814
static int zddGroupSiftingDown(DdManager *table, int x, int xHigh, Move **moves)
Definition: cuddInt.c:27322
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
static int zddGroupSiftingBackward(DdManager *table, Move *moves, int size)
Definition: cuddInt.c:27588
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
static int zddGroupSiftingUp(DdManager *table, int y, int xLow, Move **moves)
Definition: cuddInt.c:27245
FILE * out
Definition: cuddInt.h:423
DdHalfWord x
Definition: cuddInt.h:470
static int result
Definition: cuddInt.c:7466
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddGroupSiftingBackward()

static int zddGroupSiftingBackward ( DdManager table,
Move moves,
int  size 
)
static

Function********************************************************************

Synopsis [Determines the best position for a variables and returns it there.]

Description [Determines the best position for a variables and returns it there. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 27588 of file cuddInt.c.

27592 {
27593  Move *move;
27594  int res;
27595 
27596 
27597  for (move = moves; move != NULL; move = move->next) {
27598  if (move->size < size) {
27599  size = move->size;
27600  }
27601  }
27602 
27603  for (move = moves; move != NULL; move = move->next) {
27604  if (move->size == size) return(1);
27605  if ((table->subtableZ[move->x].next == move->x) &&
27606  (table->subtableZ[move->y].next == move->y)) {
27607  res = cuddZddSwapInPlace(table,(int)move->x,(int)move->y);
27608  if (!res) return(0);
27609 #ifdef DD_DEBUG
27610  if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingBackward:\n");
27611  assert(table->subtableZ[move->x].next == move->x);
27612  assert(table->subtableZ[move->y].next == move->y);
27613 #endif
27614  } else { /* Group move necessary */
27615  res = zddGroupMoveBackward(table,(int)move->x,(int)move->y);
27616  if (!res) return(0);
27617  }
27618  }
27619 
27620  return(1);
27621 
27622 } /* end of zddGroupSiftingBackward */
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
FILE * out
Definition: cuddInt.h:423
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
static int zddGroupMoveBackward(DdManager *table, int x, int y)
Definition: cuddInt.c:27514
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
int size
Definition: cuddInt.h:473
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddGroupSiftingDown()

static int zddGroupSiftingDown ( DdManager table,
int  x,
int  xHigh,
Move **  moves 
)
static

Function********************************************************************

Synopsis [Sifts down a variable until it reaches position xHigh.]

Description [Sifts down a variable until it reaches position xHigh. Assumes that x is the bottom of a group (or a singleton). Records all the moves. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 27322 of file cuddInt.c.

27327 {
27328  Move *move;
27329  int y;
27330  int size;
27331  int limitSize;
27332  int gybot;
27333 
27334 
27335  /* Initialize R */
27336  limitSize = size = table->keysZ;
27337  y = cuddZddNextHigh(table,x);
27338  while (y <= xHigh) {
27339  /* Find bottom of y group. */
27340  gybot = table->subtableZ[y].next;
27341  while (table->subtableZ[gybot].next != (unsigned) y)
27342  gybot = table->subtableZ[gybot].next;
27343 
27344  if (table->subtableZ[x].next == (unsigned) x &&
27345  table->subtableZ[y].next == (unsigned) y) {
27346  /* x and y are self groups */
27347  size = cuddZddSwapInPlace(table,x,y);
27348 #ifdef DD_DEBUG
27349  assert(table->subtableZ[x].next == (unsigned) x);
27350  assert(table->subtableZ[y].next == (unsigned) y);
27351 #endif
27352  if (size == 0) goto zddGroupSiftingDownOutOfMem;
27353 
27354  /* Record move. */
27355  move = (Move *) cuddDynamicAllocNode(table);
27356  if (move == NULL) goto zddGroupSiftingDownOutOfMem;
27357  move->x = x;
27358  move->y = y;
27359  move->flags = MTR_DEFAULT;
27360  move->size = size;
27361  move->next = *moves;
27362  *moves = move;
27363 
27364 #ifdef DD_DEBUG
27365  if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingDown (2 single groups):\n");
27366 #endif
27367  if ((double) size > (double) limitSize * table->maxGrowth)
27368  return(1);
27369  if (size < limitSize) limitSize = size;
27370  x = y;
27371  y = cuddZddNextHigh(table,x);
27372  } else { /* Group move */
27373  size = zddGroupMove(table,x,y,moves);
27374  if (size == 0) goto zddGroupSiftingDownOutOfMem;
27375  if ((double) size > (double) limitSize * table->maxGrowth)
27376  return(1);
27377  if (size < limitSize) limitSize = size;
27378  }
27379  x = gybot;
27380  y = cuddZddNextHigh(table,x);
27381  }
27382 
27383  return(1);
27384 
27385  zddGroupSiftingDownOutOfMem:
27386  while (*moves != NULL) {
27387  move = (*moves)->next;
27388  cuddDeallocMove(table, *moves);
27389  *moves = move;
27390  }
27391 
27392  return(0);
27393 
27394 } /* end of zddGroupSiftingDown */
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:29814
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
#define MTR_DEFAULT
Definition: mtr.h:94
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
static int zddGroupMove(DdManager *table, int x, int y, Move **moves)
Definition: cuddInt.c:27408
unsigned int keysZ
Definition: cuddInt.h:354
int size
Definition: cuddInt.h:473
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddGroupSiftingUp()

static int zddGroupSiftingUp ( DdManager table,
int  y,
int  xLow,
Move **  moves 
)
static

Function********************************************************************

Synopsis [Sifts up a variable until either it reaches position xLow or the size of the DD heap increases too much.]

Description [Sifts up a variable until either it reaches position xLow or the size of the DD heap increases too much. Assumes that y is the top of a group (or a singleton). Checks y for aggregation to the adjacent variables. Records all the moves that are appended to the list of moves received as input and returned as a side effect. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 27245 of file cuddInt.c.

27250 {
27251  Move *move;
27252  int x;
27253  int size;
27254  int gxtop;
27255  int limitSize;
27256 
27257  limitSize = table->keysZ;
27258 
27259  x = cuddZddNextLow(table,y);
27260  while (x >= xLow) {
27261  gxtop = table->subtableZ[x].next;
27262  if (table->subtableZ[x].next == (unsigned) x &&
27263  table->subtableZ[y].next == (unsigned) y) {
27264  /* x and y are self groups */
27265  size = cuddZddSwapInPlace(table,x,y);
27266 #ifdef DD_DEBUG
27267  assert(table->subtableZ[x].next == (unsigned) x);
27268  assert(table->subtableZ[y].next == (unsigned) y);
27269 #endif
27270  if (size == 0) goto zddGroupSiftingUpOutOfMem;
27271  move = (Move *)cuddDynamicAllocNode(table);
27272  if (move == NULL) goto zddGroupSiftingUpOutOfMem;
27273  move->x = x;
27274  move->y = y;
27275  move->flags = MTR_DEFAULT;
27276  move->size = size;
27277  move->next = *moves;
27278  *moves = move;
27279 
27280 #ifdef DD_DEBUG
27281  if (pr > 0) (void) fprintf(table->out,"zddGroupSiftingUp (2 single groups):\n");
27282 #endif
27283  if ((double) size > (double) limitSize * table->maxGrowth)
27284  return(1);
27285  if (size < limitSize) limitSize = size;
27286  } else { /* group move */
27287  size = zddGroupMove(table,x,y,moves);
27288  if (size == 0) goto zddGroupSiftingUpOutOfMem;
27289  if ((double) size > (double) limitSize * table->maxGrowth)
27290  return(1);
27291  if (size < limitSize) limitSize = size;
27292  }
27293  y = gxtop;
27294  x = cuddZddNextLow(table,y);
27295  }
27296 
27297  return(1);
27298 
27299  zddGroupSiftingUpOutOfMem:
27300  while (*moves != NULL) {
27301  move = (*moves)->next;
27302  cuddDeallocMove(table, *moves);
27303  *moves = move;
27304  }
27305  return(0);
27306 
27307 } /* end of zddGroupSiftingUp */
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
#define assert(ex)
Definition: util.h:141
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
#define MTR_DEFAULT
Definition: mtr.h:94
FILE * out
Definition: cuddInt.h:423
unsigned int flags
Definition: cuddInt.h:472
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddInt.c:29836
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
unsigned int next
Definition: cuddInt.h:317
struct Move * next
Definition: cuddInt.h:474
static int zddGroupMove(DdManager *table, int x, int y, Move **moves)
Definition: cuddInt.c:27408
unsigned int keysZ
Definition: cuddInt.h:354
int size
Definition: cuddInt.h:473
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddMergeGroups()

static void zddMergeGroups ( DdManager table,
MtrNode treenode,
int  low,
int  high 
)
static

Function********************************************************************

Synopsis [Merges groups in the DD table.]

Description [Creates a single group from low to high and adjusts the idex field of the tree node.]

SideEffects [None]

Definition at line 27636 of file cuddInt.c.

27641 {
27642  int i;
27643  MtrNode *auxnode;
27644  int saveindex;
27645  int newindex;
27646 
27647  /* Merge all variables from low to high in one group, unless
27648  ** this is the topmost group. In such a case we do not merge lest
27649  ** we lose the symmetry information. */
27650  if (treenode != table->treeZ) {
27651  for (i = low; i < high; i++)
27652  table->subtableZ[i].next = i+1;
27653  table->subtableZ[high].next = low;
27654  }
27655 
27656  /* Adjust the index fields of the tree nodes. If a node is the
27657  ** first child of its parent, then the parent may also need adjustment. */
27658  saveindex = treenode->index;
27659  newindex = table->invpermZ[low];
27660  auxnode = treenode;
27661  do {
27662  auxnode->index = newindex;
27663  if (auxnode->parent == NULL ||
27664  (int) auxnode->parent->index != saveindex)
27665  break;
27666  auxnode = auxnode->parent;
27667  } while (1);
27668  return;
27669 
27670 } /* end of zddMergeGroups */
int * invpermZ
Definition: cuddInt.h:372
struct MtrNode * parent
Definition: mtr.h:131
MtrHalfWord index
Definition: mtr.h:130
Definition: mtr.h:126
unsigned int next
Definition: cuddInt.h:317
MtrNode * treeZ
Definition: cuddInt.h:409
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddReorderChildren()

static int zddReorderChildren ( DdManager table,
MtrNode treenode,
Cudd_ReorderingType  method 
)
static

Function********************************************************************

Synopsis [Reorders the children of a group tree node according to the options.]

Description [Reorders the children of a group tree node according to the options. After reordering puts all the variables in the group and/or its descendents in a single group. This allows hierarchical reordering. If the variables in the group do not exist yet, simply does nothing. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 26759 of file cuddInt.c.

26763 {
26764  int lower;
26765  int upper;
26766  int result;
26767  unsigned int initialSize;
26768 
26769  zddFindNodeHiLo(table,treenode,&lower,&upper);
26770  /* If upper == -1 these variables do not exist yet. */
26771  if (upper == -1)
26772  return(1);
26773 
26774  if (treenode->flags == MTR_FIXED) {
26775  result = 1;
26776  } else {
26777 #ifdef DD_STATS
26778  (void) fprintf(table->out," ");
26779 #endif
26780  switch (method) {
26781  case CUDD_REORDER_RANDOM:
26783  result = cuddZddSwapping(table,lower,upper,method);
26784  break;
26785  case CUDD_REORDER_SIFT:
26786  result = cuddZddSifting(table,lower,upper);
26787  break;
26789  do {
26790  initialSize = table->keysZ;
26791  result = cuddZddSifting(table,lower,upper);
26792  if (initialSize <= table->keysZ)
26793  break;
26794 #ifdef DD_STATS
26795  else
26796  (void) fprintf(table->out,"\n");
26797 #endif
26798  } while (result != 0);
26799  break;
26801  result = cuddZddSymmSifting(table,lower,upper);
26802  break;
26804  result = cuddZddSymmSiftingConv(table,lower,upper);
26805  break;
26807  result = zddGroupSifting(table,lower,upper);
26808  break;
26809  case CUDD_REORDER_LINEAR:
26810  result = cuddZddLinearSifting(table,lower,upper);
26811  break;
26813  do {
26814  initialSize = table->keysZ;
26815  result = cuddZddLinearSifting(table,lower,upper);
26816  if (initialSize <= table->keysZ)
26817  break;
26818 #ifdef DD_STATS
26819  else
26820  (void) fprintf(table->out,"\n");
26821 #endif
26822  } while (result != 0);
26823  break;
26824  default:
26825  return(0);
26826  }
26827  }
26828 
26829  /* Create a single group for all the variables that were sifted,
26830  ** so that they will be treated as a single block by successive
26831  ** invocations of zddGroupSifting.
26832  */
26833  zddMergeGroups(table,treenode,lower,upper);
26834 
26835 #ifdef DD_DEBUG
26836  if (pr > 0) (void) fprintf(table->out,"zddReorderChildren:");
26837 #endif
26838 
26839  return(result);
26840 
26841 } /* end of zddReorderChildren */
static void zddMergeGroups(DdManager *table, MtrNode *treenode, int low, int high)
Definition: cuddInt.c:27636
MtrHalfWord flags
Definition: mtr.h:127
#define MTR_FIXED
Definition: mtr.h:97
int cuddZddSymmSiftingConv(DdManager *table, int lower, int upper)
Definition: cuddInt.c:32357
static void zddFindNodeHiLo(DdManager *table, MtrNode *treenode, int *lower, int *upper)
Definition: cuddInt.c:26860
FILE * out
Definition: cuddInt.h:423
int cuddZddSifting(DdManager *table, int lower, int upper)
Definition: cuddInt.c:30268
int cuddZddLinearSifting(DdManager *table, int lower, int upper)
Definition: cuddInt.c:28625
int cuddZddSymmSifting(DdManager *table, int lower, int upper)
Definition: cuddInt.c:32232
static int zddGroupSifting(DdManager *table, int lower, int upper)
Definition: cuddInt.c:26963
int cuddZddSwapping(DdManager *table, int lower, int upper, Cudd_ReorderingType heuristic)
Definition: cuddInt.c:30147
static int result
Definition: cuddInt.c:7466
unsigned int keysZ
Definition: cuddInt.h:354

◆ zddReorderPostprocess()

static int zddReorderPostprocess ( DdManager table)
static

Function********************************************************************

Synopsis [Shrinks almost empty ZDD subtables at the end of reordering to guarantee that they have a reasonable load factor.]

Description [Shrinks almost empty subtables at the end of reordering to guarantee that they have a reasonable load factor. However, if there many nodes are being reclaimed, then no resizing occurs. Returns 1 in case of success; 0 otherwise.]

SideEffects [None]

Definition at line 30844 of file cuddInt.c.

30846 {
30847  int i, j, posn;
30848  DdNodePtr *nodelist, *oldnodelist;
30849  DdNode *node, *next;
30850  unsigned int slots, oldslots;
30851  extern DD_OOMFP MMoutOfMemory;
30852  DD_OOMFP saveHandler;
30853 
30854 #ifdef DD_VERBOSE
30855  (void) fflush(table->out);
30856 #endif
30857 
30858  /* If we have very many reclaimed nodes, we do not want to shrink
30859  ** the subtables, because this will lead to more garbage
30860  ** collections. More garbage collections mean shorter mean life for
30861  ** nodes with zero reference count; hence lower probability of finding
30862  ** a result in the cache.
30863  */
30864  if (table->reclaimed > table->allocated * 0.5) return(1);
30865 
30866  /* Resize subtables. */
30867  for (i = 0; i < table->sizeZ; i++) {
30868  int shift;
30869  oldslots = table->subtableZ[i].slots;
30870  if (oldslots < table->subtableZ[i].keys * DD_MAX_SUBTABLE_SPARSITY ||
30871  oldslots <= table->initSlots) continue;
30872  oldnodelist = table->subtableZ[i].nodelist;
30873  slots = oldslots >> 1;
30874  saveHandler = MMoutOfMemory;
30875  MMoutOfMemory = Cudd_OutOfMem;
30876  nodelist = ALLOC(DdNodePtr, slots);
30877  MMoutOfMemory = saveHandler;
30878  if (nodelist == NULL) {
30879  return(1);
30880  }
30881  table->subtableZ[i].nodelist = nodelist;
30882  table->subtableZ[i].slots = slots;
30883  table->subtableZ[i].shift++;
30884  table->subtableZ[i].maxKeys = slots * DD_MAX_SUBTABLE_DENSITY;
30885 #ifdef DD_VERBOSE
30886  (void) fprintf(table->err,
30887  "shrunk layer %d (%d keys) from %d to %d slots\n",
30888  i, table->subtableZ[i].keys, oldslots, slots);
30889 #endif
30890 
30891  for (j = 0; (unsigned) j < slots; j++) {
30892  nodelist[j] = NULL;
30893  }
30894  shift = table->subtableZ[i].shift;
30895  for (j = 0; (unsigned) j < oldslots; j++) {
30896  node = oldnodelist[j];
30897  while (node != NULL) {
30898  next = node->next;
30899  posn = ddHash(cuddT(node), cuddE(node), shift);
30900  node->next = nodelist[posn];
30901  nodelist[posn] = node;
30902  node = next;
30903  }
30904  }
30905  FREE(oldnodelist);
30906 
30907  table->memused += (slots - oldslots) * sizeof(DdNode *);
30908  table->slots += slots - oldslots;
30909  table->minDead = (unsigned) (table->gcFrac * (double) table->slots);
30910  table->cacheSlack = (int) ddMin(table->maxCacheHard,
30912  2 * (int) table->cacheSlots;
30913  }
30914  /* We don't look at the constant subtable, because it is not
30915  ** affected by reordering.
30916  */
30917 
30918  return(1);
30919 
30920 } /* end of zddReorderPostprocess */
unsigned int keys
Definition: cuddInt.h:314
#define ddHash(f, g, s)
Definition: cuddInt.h:696
double allocated
Definition: cuddInt.h:365
Definition: cudd.h:264
#define FREE(obj)
Definition: util.h:80
double gcFrac
Definition: cuddInt.h:359
unsigned int maxCacheHard
Definition: cuddInt.h:343
unsigned int slots
Definition: cuddInt.h:352
FILE * err
Definition: cuddInt.h:424
#define DD_MAX_SUBTABLE_DENSITY
Definition: cuddInt.h:127
void(* DD_OOMFP)(long)
Definition: cudd.h:300
unsigned int cacheSlots
Definition: cuddInt.h:337
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
DdNode * next
Definition: cudd.h:267
unsigned int maxKeys
Definition: cuddInt.h:315
DdNode ** nodelist
Definition: cuddInt.h:311
#define ddMin(x, y)
Definition: cuddInt.h:771
#define DD_MAX_CACHE_TO_SLOTS_RATIO
Definition: cuddInt.h:145
int cacheSlack
Definition: cuddInt.h:342
#define cuddT(node)
Definition: cuddInt.h:609
void(* MMoutOfMemory)(long)
Definition: util.c:105
unsigned long memused
Definition: cuddInt.h:429
#define DD_MAX_SUBTABLE_SPARSITY
Definition: cuddInt.c:29525
int sizeZ
Definition: cuddInt.h:346
unsigned int slots
Definition: cuddInt.h:313
#define cuddE(node)
Definition: cuddInt.h:625
void Cudd_OutOfMem(long size)
Definition: cuddInt.c:22982
int shift
Definition: cuddInt.h:312
unsigned int minDead
Definition: cuddInt.h:358
double reclaimed
Definition: cuddInt.h:367
DdSubtable * subtableZ
Definition: cuddInt.h:350

◆ zddReorderPreprocess()

static void zddReorderPreprocess ( DdManager table)
static

Function********************************************************************

Synopsis [Prepares the ZDD heap for dynamic reordering.]

Description [Prepares the ZDD heap for dynamic reordering. Does garbage collection, to guarantee that there are no dead nodes; and clears the cache, which is invalidated by dynamic reordering.]

SideEffects [None]

Definition at line 30815 of file cuddInt.c.

30817 {
30818 
30819  /* Clear the cache. */
30820  cuddCacheFlush(table);
30821 
30822  /* Eliminate dead nodes. Do not scan the cache again. */
30823  cuddGarbageCollect(table,0);
30824 
30825  return;
30826 
30827 } /* end of ddReorderPreprocess */
int cuddGarbageCollect(DdManager *unique, int clearCache)
Definition: cuddInt.c:20120
void cuddCacheFlush(DdManager *table)
Definition: cuddInt.c:5070

◆ zddShuffle()

static int zddShuffle ( DdManager table,
int *  permutation 
)
static

Function********************************************************************

Synopsis [Reorders ZDD variables according to a given permutation.]

Description [Reorders ZDD variables according to a given permutation. The i-th permutation array contains the index of the variable that should be brought to the i-th level. zddShuffle assumes that no dead nodes are present. The reordering is achieved by a series of upward sifts. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

SeeAlso []

Definition at line 30939 of file cuddInt.c.

30942 {
30943  int index;
30944  int level;
30945  int position;
30946  int numvars;
30947  int result;
30948 #ifdef DD_STATS
30949  unsigned long localTime;
30950  int initialSize;
30951  int finalSize;
30952  int previousSize;
30953 #endif
30954 
30956 #ifdef DD_STATS
30957  localTime = util_cpu_time();
30958  initialSize = table->keysZ;
30959  (void) fprintf(table->out,"#:I_SHUFFLE %8d: initial size\n",
30960  initialSize);
30961 #endif
30962 
30963  numvars = table->sizeZ;
30964 
30965  for (level = 0; level < numvars; level++) {
30966  index = permutation[level];
30967  position = table->permZ[index];
30968 #ifdef DD_STATS
30969  previousSize = table->keysZ;
30970 #endif
30971  result = zddSiftUp(table,position,level);
30972  if (!result) return(0);
30973 #ifdef DD_STATS
30974  if (table->keysZ < (unsigned) previousSize) {
30975  (void) fprintf(table->out,"-");
30976  } else if (table->keysZ > (unsigned) previousSize) {
30977  (void) fprintf(table->out,"+"); /* should never happen */
30978  } else {
30979  (void) fprintf(table->out,"=");
30980  }
30981  fflush(table->out);
30982 #endif
30983  }
30984 
30985 #ifdef DD_STATS
30986  (void) fprintf(table->out,"\n");
30987  finalSize = table->keysZ;
30988  (void) fprintf(table->out,"#:F_SHUFFLE %8d: final size\n",finalSize);
30989  (void) fprintf(table->out,"#:T_SHUFFLE %8g: total time (sec)\n",
30990  ((double)(util_cpu_time() - localTime)/1000.0));
30991  (void) fprintf(table->out,"#:N_SHUFFLE %8d: total swaps\n",
30993 #endif
30994 
30995  return(1);
30996 
30997 } /* end of zddShuffle */
static int zddSiftUp(DdManager *table, int x, int xLow)
Definition: cuddInt.c:31014
int * permZ
Definition: cuddInt.h:370
static int numvars
Definition: cuddInt.c:7452
FILE * out
Definition: cuddInt.h:423
long util_cpu_time(void)
Definition: util.c:34
int zddTotalNumberSwapping
Definition: cuddInt.c:28565
int sizeZ
Definition: cuddInt.h:346
static int result
Definition: cuddInt.c:7466
unsigned int keysZ
Definition: cuddInt.h:354

◆ zddSiftUp()

static int zddSiftUp ( DdManager table,
int  x,
int  xLow 
)
static

Function********************************************************************

Synopsis [Moves one ZDD variable up.]

Description [Takes a ZDD variable from position x and sifts it up to position xLow; xLow should be less than or equal to x. Returns 1 if successful; 0 otherwise]

SideEffects [None]

SeeAlso []

Definition at line 31014 of file cuddInt.c.

31018 {
31019  int y;
31020  int size;
31021 
31022  y = cuddZddNextLow(table,x);
31023  while (y >= xLow) {
31024  size = cuddZddSwapInPlace(table,y,x);
31025  if (size == 0) {
31026  return(0);
31027  }
31028  x = y;
31029  y = cuddZddNextLow(table,x);
31030  }
31031  return(1);
31032 
31033 } /* end of zddSiftUp */
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddInt.c:29836
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885

◆ zddSwapAny()

static Move * zddSwapAny ( DdManager table,
int  x,
int  y 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Swaps any two variables.]

Description [Swaps any two variables. Returns the set of moves.]

SideEffects [None]

SeeAlso []

Definition at line 30366 of file cuddInt.c.

30370 {
30371  Move *move, *moves;
30372  int tmp, size;
30373  int x_ref, y_ref;
30374  int x_next, y_next;
30375  int limit_size;
30376 
30377  if (x > y) { /* make x precede y */
30378  tmp = x; x = y; y = tmp;
30379  }
30380 
30381  x_ref = x; y_ref = y;
30382 
30383  x_next = cuddZddNextHigh(table, x);
30384  y_next = cuddZddNextLow(table, y);
30385  moves = NULL;
30386  limit_size = table->keysZ;
30387 
30388  for (;;) {
30389  if (x_next == y_next) { /* x < x_next = y_next < y */
30390  size = cuddZddSwapInPlace(table, x, x_next);
30391  if (size == 0)
30392  goto zddSwapAnyOutOfMem;
30393  move = (Move *) cuddDynamicAllocNode(table);
30394  if (move == NULL)
30395  goto zddSwapAnyOutOfMem;
30396  move->x = x;
30397  move->y = x_next;
30398  move->size = size;
30399  move->next = moves;
30400  moves = move;
30401 
30402  size = cuddZddSwapInPlace(table, y_next, y);
30403  if (size == 0)
30404  goto zddSwapAnyOutOfMem;
30405  move = (Move *)cuddDynamicAllocNode(table);
30406  if (move == NULL)
30407  goto zddSwapAnyOutOfMem;
30408  move->x = y_next;
30409  move->y = y;
30410  move->size = size;
30411  move->next = moves;
30412  moves = move;
30413 
30414  size = cuddZddSwapInPlace(table, x, x_next);
30415  if (size == 0)
30416  goto zddSwapAnyOutOfMem;
30417  move = (Move *)cuddDynamicAllocNode(table);
30418  if (move == NULL)
30419  goto zddSwapAnyOutOfMem;
30420  move->x = x;
30421  move->y = x_next;
30422  move->size = size;
30423  move->next = moves;
30424  moves = move;
30425 
30426  tmp = x; x = y; y = tmp;
30427 
30428  } else if (x == y_next) { /* x = y_next < y = x_next */
30429  size = cuddZddSwapInPlace(table, x, x_next);
30430  if (size == 0)
30431  goto zddSwapAnyOutOfMem;
30432  move = (Move *)cuddDynamicAllocNode(table);
30433  if (move == NULL)
30434  goto zddSwapAnyOutOfMem;
30435  move->x = x;
30436  move->y = x_next;
30437  move->size = size;
30438  move->next = moves;
30439  moves = move;
30440 
30441  tmp = x; x = y; y = tmp;
30442  } else {
30443  size = cuddZddSwapInPlace(table, x, x_next);
30444  if (size == 0)
30445  goto zddSwapAnyOutOfMem;
30446  move = (Move *)cuddDynamicAllocNode(table);
30447  if (move == NULL)
30448  goto zddSwapAnyOutOfMem;
30449  move->x = x;
30450  move->y = x_next;
30451  move->size = size;
30452  move->next = moves;
30453  moves = move;
30454 
30455  size = cuddZddSwapInPlace(table, y_next, y);
30456  if (size == 0)
30457  goto zddSwapAnyOutOfMem;
30458  move = (Move *)cuddDynamicAllocNode(table);
30459  if (move == NULL)
30460  goto zddSwapAnyOutOfMem;
30461  move->x = y_next;
30462  move->y = y;
30463  move->size = size;
30464  move->next = moves;
30465  moves = move;
30466 
30467  x = x_next; y = y_next;
30468  }
30469 
30470  x_next = cuddZddNextHigh(table, x);
30471  y_next = cuddZddNextLow(table, y);
30472  if (x_next > y_ref)
30473  break; /* if x == y_ref */
30474 
30475  if ((double) size > table->maxGrowth * (double) limit_size)
30476  break;
30477  if (size < limit_size)
30478  limit_size = size;
30479  }
30480  if (y_next >= x_ref) {
30481  size = cuddZddSwapInPlace(table, y_next, y);
30482  if (size == 0)
30483  goto zddSwapAnyOutOfMem;
30484  move = (Move *)cuddDynamicAllocNode(table);
30485  if (move == NULL)
30486  goto zddSwapAnyOutOfMem;
30487  move->x = y_next;
30488  move->y = y;
30489  move->size = size;
30490  move->next = moves;
30491  moves = move;
30492  }
30493 
30494  return(moves);
30495 
30496  zddSwapAnyOutOfMem:
30497  while (moves != NULL) {
30498  move = moves->next;
30499  cuddDeallocMove(table, moves);
30500  moves = move;
30501  }
30502  return(NULL);
30503 
30504 } /* end of zddSwapAny */
int cuddZddNextHigh(DdManager *table, int x)
Definition: cuddInt.c:29814
#define cuddDeallocMove(unique, node)
Definition: cuddInt.h:537
Definition: cuddInt.h:469
DdNode * cuddDynamicAllocNode(DdManager *table)
Definition: cuddInt.c:14727
double maxGrowth
Definition: cuddInt.h:397
DdHalfWord x
Definition: cuddInt.h:470
int cuddZddNextLow(DdManager *table, int x)
Definition: cuddInt.c:29836
int cuddZddSwapInPlace(DdManager *table, int x, int y)
Definition: cuddInt.c:29885
DdHalfWord y
Definition: cuddInt.h:471
struct Move * next
Definition: cuddInt.h:474
unsigned int keysZ
Definition: cuddInt.h:354
int size
Definition: cuddInt.h:473

◆ zddTreeSiftingAux()

static int zddTreeSiftingAux ( DdManager table,
MtrNode treenode,
Cudd_ReorderingType  method 
)
static

AutomaticStart

Function********************************************************************

Synopsis [Visits the group tree and reorders each group.]

Description [Recursively visits the group tree and reorders each group in postorder fashion. Returns 1 if successful; 0 otherwise.]

SideEffects [None]

Definition at line 26675 of file cuddInt.c.

26679 {
26680  MtrNode *auxnode;
26681  int res;
26682 
26683 #ifdef DD_DEBUG
26684  Mtr_PrintGroups(treenode,1);
26685 #endif
26686 
26687  auxnode = treenode;
26688  while (auxnode != NULL) {
26689  if (auxnode->child != NULL) {
26690  if (!zddTreeSiftingAux(table, auxnode->child, method))
26691  return(0);
26692  res = zddReorderChildren(table, auxnode, CUDD_REORDER_GROUP_SIFT);
26693  if (res == 0)
26694  return(0);
26695  } else if (auxnode->size > 1) {
26696  if (!zddReorderChildren(table, auxnode, method))
26697  return(0);
26698  }
26699  auxnode = auxnode->younger;
26700  }
26701 
26702  return(1);
26703 
26704 } /* end of zddTreeSiftingAux */
MtrHalfWord size
Definition: mtr.h:129
struct MtrNode * younger
Definition: mtr.h:134
static int zddReorderChildren(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddInt.c:26759
Definition: mtr.h:126
void Mtr_PrintGroups(MtrNode *root, int silent)
Definition: mtr.c:773
static int zddTreeSiftingAux(DdManager *table, MtrNode *treenode, Cudd_ReorderingType method)
Definition: cuddInt.c:26675
struct MtrNode * child
Definition: mtr.h:132

◆ zddUniqueCompareGroup()

static int zddUniqueCompareGroup ( int *  ptrX,
int *  ptrY 
)
static

Function********************************************************************

Synopsis [Comparison function used by qsort.]

Description [Comparison function used by qsort to order the variables according to the number of keys in the subtables. Returns the difference in number of keys between the two variables being compared.]

SideEffects [None]

Definition at line 26935 of file cuddInt.c.

26938 {
26939 #if 0
26940  if (entry[*ptrY] == entry[*ptrX]) {
26941  return((*ptrX) - (*ptrY));
26942  }
26943 #endif
26944  return(entry[*ptrY] - entry[*ptrX]);
26945 
26946 } /* end of zddUniqueCompareGroup */
static int * entry
Definition: cuddInt.c:8422

◆ zddVarToConst()

static void zddVarToConst ( DdNode f,
DdNode **  gp,
DdNode **  hp,
DdNode base,
DdNode empty 
)
static

Function********************************************************************

Synopsis [Replaces variables with constants if possible (part of canonical form).]

Description []

SideEffects [None]

SeeAlso []

Definition at line 31961 of file cuddInt.c.

31967 {
31968  DdNode *g = *gp;
31969  DdNode *h = *hp;
31970 
31971  if (f == g) { /* ITE(F,F,H) = ITE(F,1,H) = F + H */
31972  *gp = base;
31973  }
31974 
31975  if (f == h) { /* ITE(F,G,F) = ITE(F,G,0) = F * G */
31976  *hp = empty;
31977  }
31978 
31979 } /* end of zddVarToConst */
Definition: cudd.h:264
static DdNode * empty
Definition: cuddInt.c:28567

Variable Documentation

◆ background

DdNode* background
static

Definition at line 22141 of file cuddInt.c.

◆ computed

st_table* computed
static

Definition at line 7462 of file cuddInt.c.

◆ cross

int cross
static

Definition at line 7467 of file cuddInt.c.

◆ cuddRand

long cuddRand = 0
static

Definition at line 22143 of file cuddInt.c.

◆ cuddRand2

long cuddRand2
static

Definition at line 22144 of file cuddInt.c.

◆ DD_UNUSED

char rcsid [] DD_UNUSED = "$Id: cuddAddIte.c,v 1.16 2012/02/05 01:07:18 fabio Exp $"
static

CFile***********************************************************************

FileName [cuddAddIte.c]

PackageName [cudd]

Synopsis [ADD ITE function and satellites.]

Description [External procedures included in this module:

Internal procedures included in this module:

Static procedures included in this module:

]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 86 of file cuddInt.c.

◆ ddTotalNumberSwapping

int ddTotalNumberSwapping

Definition at line 14489 of file cuddInt.c.

◆ empty

static DdNode * empty
static

Definition at line 28567 of file cuddInt.c.

◆ entry

static int * entry
static

CFile***********************************************************************

FileName [cuddZddGroup.c]

PackageName [cudd]

Synopsis [Functions for ZDD group sifting.]

Description [External procedures included in this file:

  • Cudd_MakeZddTreeNode()

Internal procedures included in this file:

Static procedures included in this module:

]

Author [Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 8422 of file cuddInt.c.

◆ large

int large
static

Definition at line 7464 of file cuddInt.c.

◆ numvars

int numvars
static

Definition at line 7452 of file cuddInt.c.

◆ one

DdNode* one
static

Definition at line 16562 of file cuddInt.c.

◆ originalSize

unsigned int originalSize
static

Definition at line 8436 of file cuddInt.c.

◆ popsize

int popsize
static

CFile***********************************************************************

FileName [cuddGenetic.c]

PackageName [cudd]

Synopsis [Genetic algorithm for variable reordering.]

Description [Internal procedures included in this file:

Static procedures included in this module:

The genetic algorithm implemented here is as follows. We start with the current DD order. We sift this order and use this as the reference DD. We only keep 1 DD around for the entire process and simply rearrange the order of this DD, storing the various orders and their corresponding DD sizes. We generate more random orders to build an initial population. This initial population is 3 times the number of variables, with a maximum of 120. Each random order is built (from the reference DD) and its size stored. Each random order is also sifted to keep the DD sizes fairly small. Then a crossover is performed between two orders (picked randomly) and the two resulting DDs are built and sifted. For each new order, if its size is smaller than any DD in the population, it is inserted into the population and the DD with the largest number of nodes is thrown out. The crossover process happens up to 50 times, and at this point the DD in the population with the smallest size is chosen as the result. This DD must then be built from the reference DD.]

SeeAlso []

Author [Curt Musfeldt, Alan Shuler, Fabio Somenzi]

Copyright [Copyright (c) 1995-2012, Regents of the University of Colorado

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the University of Colorado nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.]

Definition at line 7451 of file cuddInt.c.

◆ repeat

int* repeat
static

Definition at line 7463 of file cuddInt.c.

◆ result

int result
static

Definition at line 7466 of file cuddInt.c.

◆ shuffleSelect

long shuffleSelect
static

Definition at line 22145 of file cuddInt.c.

◆ shuffleTable

long shuffleTable[STAB_SIZE]
static

Definition at line 22146 of file cuddInt.c.

◆ storedd

int* storedd
static

Definition at line 7461 of file cuddInt.c.

◆ zdd_entry

int * zdd_entry

Definition at line 29545 of file cuddInt.c.

◆ zddTotalNumberLinearTr

int zddTotalNumberLinearTr
static

Definition at line 28566 of file cuddInt.c.

◆ zddTotalNumberSwapping

int zddTotalNumberSwapping

Definition at line 28565 of file cuddInt.c.

◆ zero

static DdNode * zero
static

Definition at line 16562 of file cuddInt.c.